- 浏览: 140519 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
elephant_xiang:
condition例子,搞错了吧public void pro ...
jdk1.5的多线程总结一 -
yinlei126:
这么好的文章没有评论,谢谢
Mina框架剖析--动态篇 -
xds2008:
写的不错,值得表扬,测了一下,还不错,就是有点慢,但是最起码远 ...
java实现远程桌面监控 -
exp111:
这个确实很强 但是能不能连接一次不停的传呢 这个好像是必须连一 ...
java实现远程桌面监控 -
seeallsea:
不错!可以相互转换了。
keystore证书转换
6.Thread-Per-Message模式
这个模式在swing开发中随处可见。比如我们希望点击一个按钮就启动文件系统扫描程序,一般的做法就是
简单的理解就是来一个请求,开启一个线程去处理请求。这样的应用场景也见于Servlet容器处理http请求,socket处理文件读写操作等。这个设计主要是用来解决一些耗时的操作,提高响应性,但是同时也会产生额外的线程的启动开销和无法得到响应结果。创建和销毁线程本身就有一定的开销,如果频繁创建和销毁线程,CPU和内存开销就不可忽略,垃圾收集器还必须负担更多的工作。为解决线程开销的问题,有了worker线程模式;为解决响应结果的问题,有了Future模式。
7.Worker线程模式
先初始化一个线程池,所有线程处于阻塞状态。接受到一个新的请求后,就从线程池中挑选一个等待的线程并执行请求处理。处理完毕后,线程并不结束,而是转为阻塞状态再次被放入线程池中,这样就避免了频繁创建和销毁线程。以一个简单的例子。
首先是请求类Request
再是请求处理器,它会接收所有请求,队列缓冲起来,交给workerThread执行。
接下来是真正的workerThread.
下面是模拟并发请求的clientThread
在这个小程序里面,当队列满,采用的方式是client线程阻塞。对于一般的web服务器在用户请求繁忙时就会拒绝用户:HTTP 503 SERVICE UNAVAILABLE。
8.Future模式
Thread-Per-Message模式引申出2个问题,worker Thread解决了一个,Future就是用来解决另一个的。我个人理解就是,在请求发出后,马上可以获取返回值Future,但是这个返回值Future并不是真正的值,因为线程还在跑呢,跑完之前不会有结果出来的。Future中有个getContent方法就是获取真正的返回值的,但是这个方法是阻塞性的,结果返回之前是不会跳出来的。
首先是Future接口。
然后是它的实现类。
再是真实的返回数据类。
用以模拟请求处理的Host。
用个Main程序跑起来
jdk1.5后,有了真正的Future接口以及它的实现类FutureTask,实现的更为精巧,详细。
这个模式在swing开发中随处可见。比如我们希望点击一个按钮就启动文件系统扫描程序,一般的做法就是
okButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { new Thread(new Runnable(){ public void run() { doFileSystemScan(); }}).start(); }});
简单的理解就是来一个请求,开启一个线程去处理请求。这样的应用场景也见于Servlet容器处理http请求,socket处理文件读写操作等。这个设计主要是用来解决一些耗时的操作,提高响应性,但是同时也会产生额外的线程的启动开销和无法得到响应结果。创建和销毁线程本身就有一定的开销,如果频繁创建和销毁线程,CPU和内存开销就不可忽略,垃圾收集器还必须负担更多的工作。为解决线程开销的问题,有了worker线程模式;为解决响应结果的问题,有了Future模式。
7.Worker线程模式
先初始化一个线程池,所有线程处于阻塞状态。接受到一个新的请求后,就从线程池中挑选一个等待的线程并执行请求处理。处理完毕后,线程并不结束,而是转为阻塞状态再次被放入线程池中,这样就避免了频繁创建和销毁线程。以一个简单的例子。
首先是请求类Request
public class Request { private final String name; private final int number; private static final Random random = new Random(); public Request(String name, int number) { this.name = name; this.number = number; } public void execute() { System.out.println(Thread.currentThread().getName() + " executes " + this); try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException ignore) { } } public String toString() { return "[ Request from " + name + " No." + number + " ]"; } }
再是请求处理器,它会接收所有请求,队列缓冲起来,交给workerThread执行。
public class RequestProcesser { private static final int MAX_REQUEST = 100; private final Request[] requestQueue; private int tail; private int head; private int count; // Request的数量 private final WorkerThread[] threadPool; public RequestProcesser(int threads) { this.requestQueue = new Request[MAX_REQUEST]; this.head = 0; this.tail = 0; this.count = 0; threadPool = new WorkerThread[threads]; for (int i = 0; i < threadPool.length; i++) { threadPool[i] = new WorkerThread("Worker-" + i, this); } } /** * 启动所有工作线程 */ public void startWorkers() { for (int i = 0; i < threadPool.length; i++) { threadPool[i].start(); } } /** * 放入请求到工作队列 * @param request */ public synchronized void putRequest(Request request) { while (count >= requestQueue.length) { try { wait(); } catch (InterruptedException ignore) { } } requestQueue[tail] = request; tail = (tail + 1) % requestQueue.length; count++; notifyAll(); } /** * 得到最近的请求 * @return */ public synchronized Request takeRequest() { while (count <= 0) { try { wait(); } catch (InterruptedException ignore) { } } Request request = requestQueue[head]; head = (head + 1) % requestQueue.length; count--; notifyAll(); return request; } }
接下来是真正的workerThread.
public class WorkerThread extends Thread { private final RequestProcesser queue; public WorkerThread(String name, RequestProcesser queue) { super(name); this.queue = queue; } public void run() { while (true) { Request request = queue.takeRequest(); request.execute(); } } }
下面是模拟并发请求的clientThread
public class ClientThread extends Thread { private final RequestProcesser processer; private static final Random random = new Random(); public ClientThread(String name, RequestProcesser processer) { super(name); this.processer = processer; } public void run() { try { for (int i = 0; true; i++) { Request request = new Request(getName(), i); processer.putRequest(request); Thread.sleep(random.nextInt(1000)); } } catch (InterruptedException e) { } } }最后用个main类来跑下这个小程序。
public class Main { public static void main(String[] args) { RequestProcesser processer = new RequestProcesser(5); processer.startWorkers(); new ClientThread("hankzhang", processer).start(); new ClientThread("yashironan", processer).start(); new ClientThread("yunyunzei", processer).start(); } }
在这个小程序里面,当队列满,采用的方式是client线程阻塞。对于一般的web服务器在用户请求繁忙时就会拒绝用户:HTTP 503 SERVICE UNAVAILABLE。
8.Future模式
Thread-Per-Message模式引申出2个问题,worker Thread解决了一个,Future就是用来解决另一个的。我个人理解就是,在请求发出后,马上可以获取返回值Future,但是这个返回值Future并不是真正的值,因为线程还在跑呢,跑完之前不会有结果出来的。Future中有个getContent方法就是获取真正的返回值的,但是这个方法是阻塞性的,结果返回之前是不会跳出来的。
首先是Future接口。
public interface Future { public abstract String getContent(); }
然后是它的实现类。
public class FutureTask implements Future { private RealData realdata = null; private boolean ready = false; public synchronized void setRealData(RealData realdata) { if (ready) { return; } this.realdata = realdata; this.ready = true; notifyAll(); } public synchronized String getContent() { while (!ready) { try { wait(); } catch (InterruptedException e) { } } return realdata.getContent(); } }
再是真实的返回数据类。
public class RealData implements Future { private final String content; public RealData(int count, char c) { System.out.println(" making RealData(" + count + ", " + c + ") BEGIN"); char[] buffer = new char[count]; for (int i = 0; i < count; i++) { buffer[i] = c; try { Thread.sleep(100); } catch (InterruptedException e) { } } System.out.println(" making RealData(" + count + ", " + c + ") END"); this.content = new String(buffer); } public String getContent() { return content; } }
用以模拟请求处理的Host。
public class Host { public Future request(final int count, final char c) { System.out.println(" request(" + count + ", " + c + ") BEGIN"); //建立FutureData final FutureTask future = new FutureTask(); //建立RealData,启动新线程 new Thread() { public void run() { RealData realdata = new RealData(count, c); future.setRealData(realdata); } }.start(); System.out.println(" request(" + count + ", " + c + ") END"); //取回FutureData,作为传回值 return future; } }
用个Main程序跑起来
public class Main { public static void main(String[] args) { System.out.println("main BEGIN"); Host host = new Host(); Future data1 = host.request(10, 'A'); Future data2 = host.request(20, 'B'); Future data3 = host.request(30, 'C'); try { Thread.sleep(2000); } catch (InterruptedException e) { } System.out.println("data1 = " + data1.getContent()); System.out.println("data2 = " + data2.getContent()); System.out.println("data3 = " + data3.getContent()); System.out.println("main END"); } }
jdk1.5后,有了真正的Future接口以及它的实现类FutureTask,实现的更为精巧,详细。
发表评论
-
Java上clear Squid缓存
2011-11-29 10:26 1301实现原理: 构造TCP请求,调用Squid自带 ... -
HttpURLConnection设置代理
2011-01-21 11:00 1475设置全局代理,JVM范围内有效: System ... -
JCE provider管理的问题
2010-08-23 13:24 3260现象 两个module A和B分别采用了infosec的不同版 ... -
Jar冲突解决二
2010-08-23 11:54 1751方案思想 自定义CustomClassLoader,彻底改变c ... -
Jar冲突解决一
2010-08-23 10:46 1230目的是classpath中线性的jar排列扩展成树型排列。方案 ... -
负载均衡备注二
2010-03-30 11:41 1097Lvs或者F5的负载体系中 ... -
SelectableChannel关闭注意事项
2010-03-29 11:49 1000SocketChannel和ServerSocketChann ... -
java clone备忘
2009-12-09 14:39 8231.Object clone 就是复制一个对象的复本,在Fac ... -
远程调用之RMI
2009-05-22 00:03 1056RMI(Remote Method Invocation ... -
Java修饰符归纳
2009-05-20 17:26 928final 1.final类 final类不能被继承, ... -
classloader整理
2009-05-18 18:08 1122classloader它就是用来加载Class文件到JV ... -
Java IO归纳
2009-05-17 14:39 1656Java的IO基于装饰器模式设计。根接口是InputS ... -
java实现远程桌面监控
2009-05-10 19:28 3858java里面的Robot类可以完成截图的功能,借助于这 ... -
简单的轮子--IOC容器
2009-05-10 15:48 1140产品的需求越来越多,则开发了越来越多的功能,同时也带来了 ... -
Java也可以截图
2009-05-10 14:48 1121java.awt.Robot类真的很好玩。玩Robot会给你带 ... -
jdk1.5的多线程总结二
2009-05-10 13:07 1620新的Synchronizer: Java 5.0里新加了4个协 ... -
jdk1.5的多线程总结一
2009-05-10 01:17 6040Java 5.0里新加入了三个多线程包:java.util.c ... -
JavaGC知识整理
2009-05-08 00:55 967堆 JVM管理的内存叫堆。在32Bit操作系统上有1.5G-2 ... -
ConcurrentHashMap
2009-05-08 00:54 1029实现原理 锁分离 (Lock Stripping) C ... -
Java Socket异常整理
2009-05-08 00:41 3554最近跟进性能测试,碰 ...
相关推荐
总结起来,多线程环境下的单例模式实现需要注意线程安全问题,尤其是懒汉式单例,需要采取适当的同步措施来防止多线程环境下的实例化问题。此外,对于不同场景的需求,可以选择不同的实现方式来优化性能和资源使用。
多线程基础理论, 多线程中常用API,多线程的实现方式, 线程池以及创建线程池相关API, 常见的设计模式等内容
1. 单例模式:在多线程环境中保证单例对象的唯一性,常用双检锁/双重校验锁定(DCL)和静态内部类等方式实现。 2. 生产者-消费者模式:通过阻塞队列实现生产者线程和消费者线程之间的数据交换,利用BlockingQueue...
以上只是Java多线程设计模式的一些基本概念和常用技术,实际开发中还需要根据具体需求灵活运用,结合设计模式来解决问题。《Java 多线程设计模式》一书的源代码应该涵盖了这些知识点的具体实现,通过阅读和实践,...
设计模式则是解决软件开发中常见问题的经验总结,它为多线程环境下的编程提供了有效的解决方案。本资源包括了详细的“Java多线程设计模式详解”PDF文档以及配套的源码,帮助开发者深入理解和应用这些模式。 首先,...
### Java多线程知识点总结及企业真题解析 #### 一、知识点总结 ##### (1)多线程相关概念 1. **程序、进程和线程的区分**: - **程序**:为了完成特定的任务而编写的指令集合。它是静态的概念。 - **进程**:...
以下是对Java中常用设计模式的详细解释: 1. **单例模式**:单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于配置管理、线程池或者数据库连接池等场景。实现方式有懒汉式(线程不安全)、...
总结来说,本文档通过介绍单例模式在多核多线程环境下的性能提升方法,探讨了Java设计模式在现代大型系统应用中的优化策略,并对JDK未来的设计模式实现提出期望,为Java开发人员提供了宝贵的技术指导和参考。
### 多线程服务器的几种常用模型 #### 1. 进程与线程 在计算机科学中,**进程**和**线程**是两个重要的概念。进程是资源分配的基本单位,而线程则是调度的基本单位。每个进程都有自己的独立地址空间,这意味着不同...
### Java多线程编程环境中单例模式的实现 #### 概述 单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式的应用非常广泛,特别是在资源管理、日志记录、...
在“Java多线程学习总结6”这个主题中,我们可以深入探讨Java多线程的实现、管理及优化。下面将详细阐述相关知识点。 1. **线程的创建方式** - **继承Thread类**:自定义类继承Thread类,并重写run()方法,创建...
提供了一个包含多线程编程中常用术语的词汇表,方便读者查阅。 #### 结束语 本指南详细介绍了多线程编程在iOS开发中的应用,希望读者能够从中受益,并在实际项目中有效地运用多线程技术。 #### 推荐资源 最后,...
对于一些常用的框架,如Foundation Framework、ApplicationKit和CoreData,Apple提供了线程安全的总结,指导开发者如何在这些框架内安全地使用多线程。 以上就是iOS多线程编程指南的主要知识点,详细解读了多线程...
### C#多线程教材知识点详解 ...以上是对C#多线程教材的详细知识点总结,涵盖了从基本概念到高级主题的相关内容。掌握这些知识将有助于开发者更好地利用多线程技术,构建高效、可靠的多线程应用程序。
### Java多线程单例模式详解 #### 一、单例模式概述 单例模式(Singleton Pattern)是一种常用的软件设计模式,它确保一个类仅有一个实例,并提供一个全局访问点。这种模式通常用于那些需要频繁实例化然后销毁的...
总结,LsComm是串口通信领域的强大工具,通过多线程和多接收模式,它为开发者提供了高效、灵活的解决方案。无论是在传统的VC6环境中还是更新的VC7环境下,LsComm都能发挥出色的表现,简化串口通信的实现,提高软件的...
总结来说,支持多线程AC自动机的Snort改进版是一种高效的方法,它结合了AC自动机的快速搜索能力和多线程的并发处理能力,旨在提高网络入侵检测系统的性能和响应速度,对于应对现代网络安全挑战具有重要意义。
在多线程编程中,常用的设计模式有生产者-消费者模式、读写锁模式等。 10. 多线程工具类:Java提供了诸如Timer、ScheduledExecutorService等工具类,它们能够帮助开发者更方便地进行时间安排、任务调度等操作。 ...
### 多线程编程指南知识点总结 #### 一、多线程基础介绍 - **定义多线程术语**: - **线程**:线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。 - **多线程**:指的是...
单例模式是一种常用的创建型设计模式,它保证一个类仅有一个实例,并提供一个全局访问点。单例模式通常用于控制资源的共享访问,例如数据库连接池、日志管理器等。 #### 实现方式 - **构造函数私有化**:防止外部...