Thread-Per-Message Pattern
来源:互联网 发布:淘宝子账号 编辑:程序博客网 时间:2024/05/16 05:27
什么是Thread-Per-Message Pattern?
设想一个场景,妻子在忙着淘宝,对丈夫说,“亲爱的,能不能帮我倒一下垃圾。”,然后老公去倒垃圾,老婆继续逛淘宝,这就是Thread-Per-Message Pattern,拜托别人,“这件事就交给你了”以后再回来做自己的事。
对每个命令或者请求,分配一个线程,由这个线程执行工作。
现在有这样的需求,启动三个线程,分别输出10个A,20个B,30个C,允许字母交叉,首先看代码:
首先写一个Helper类,负责对字母进行输出:
package threadPerMessage;public class Helper { public void handle(int count, char c) { System.out.println(" handle(" + count + ", " + c + ") BEGIN"); for (int i = 0; i < count; i++) { slowly(); System.out.print(c); } System.out.println(""); System.out.println(" handle(" + count + ", " + c + ") END"); } private void slowly() { try { Thread.sleep(100); } catch (InterruptedException e) { } }}然后写一个Host类,作为Helper的宿主类,对外提供helper的方法:
package threadPerMessage;public class Host { private final Helper helper = new Helper(); public void request(final int count, final char c) { System.out.println(" request(" + count + ", " + c + ") BEGIN"); new Thread() { public void run() { helper.handle(count, c); } }.start(); System.out.println(" request(" + count + ", " + c + ") END"); }}最后写一个测试类Test:
package threadPerMessage;public class Test { public static void main(String[] args) { System.out.println("main BEGIN"); Host host = new Host(); host.request(10, 'A'); host.request(20, 'B'); host.request(30, 'C'); System.out.println("main END"); }}回过头来看代码,在Host类中我们发现了一个匿名内部类,建立了Thread子类的实例,并且启动线程:
new Thread(){ @Override public void run(){ helper.handle(count,c); }}.start();实际上是把类声明,建立实例,启动线程写在了一起。
匿名内部类:将类的声明和建立实例的操作写在一起,执行方法的时候才建立类文件。匿名类和一般类相同,都会在编译时产生出类文件。当我们在匿名内部类中用到方法的参数或者局部变量时,必须将变量声明成final,如果不是final,会发生编译错误。
Thread-Per-Message Pattern的所有参与者
1、Client(委托人)参与者
Client参与者对Host参与者发出请求,Client不知道Host如何实现这个请求,但知道他会去做。
2、Host参与者
当Host收到Client发出的请求的时候,会建立新的线程启动它,这个新的线程,会使用Helper参与者,处理这个请求。
3、Helper(帮助者)参与者
Helper参与者会对Host参与者提供处理请求的功能,Host参与者所建立的线程,会使用Helper参与者。
什么时候使用这个模式?
1、提升响应度,降低延迟时间
使用这个模式,Host对Client的响应度会提高,延迟时间会下降,尤其当处理函数很花时间或者需要等待I/O的时候,效果很明显。
2、适合在操作顺序无所谓时使用
这个模式中,handle方法执行顺序不一定时request方法调用顺序。
3、不需要返回值的时候
这个模式中,request方法不会等到handle方法执行结束,也就是说request方法拿不到handle方法的返回值。
4、应用在服务器的制作
这个模式可以在客户端送达请求,主线程接收,其他线程处理该请求的情况下使用。
5、调用方法+启动线程→传送消息
通常调用出普通方法的时候,执行完方法里的操作,控制权才会回来,然而在这个模式里request时期待才做开始的触发器,但是不会等待到执行结束(传送异步消息)。
进阶说明:进程与线程
进程与线程之间的关系,会因为平台的差异,有极大的不同,但是我们一般可以说一个进程可以建立多个线程。
线程的内存时共享的。
线程和进程最大的差异在于内存是否能共享,通常进程的内存空间是各自独立的,进程不能擅自读取、改写其他进程的内存空间。因为进程内存空间的独立性,进程无须担心被其他进程破坏。
线程则是共享内存的,所以我们进程在一条线程的内存上写入数据,而其他线程来读取。这里说的共享相同的内存,在Java中就体现为共享相同的实例。
因为线程间的内存是共享的,因此线程之间的沟通可以很自然、简单地做到。然而一位内同一个实例可以有多个线程同时访问,所以需要正确地进行互斥共享。
线程间的context-switch较容易
进程和线程的另一个差异,在于contex-switch的繁重程度。
要切换进程的时候,进程需要将当前自己的状态(context信息)存储下来,并将下一个要开始执行的进程以前所保留的context数据读回来,这个信息切换操作(context switch)所需要花费一些时间。
切换执行线程的时候,线程也需要进行context-switch操作,然而,线程所管理的context信息比进程要少,一般而言线程的context-swicth要比进程的context-switch快得多。所以需要紧密进行多项相关工作得时候,线程通常比进程来得实用。
PS、Java的内存模型中,将内存分为主存储器和工作内存两种,能够让线程共享的,只有主存储器部分。
- Thread-Per-Message Pattern
- Thread-Per-Message Pattern
- Java线程之Thread-Per-Message Pattern
- Thread-Per-Message 模式
- Thread-Per-Message 模式
- 第七章 Thread-Per-Message
- Thread-Per-message Pattern--JAVA多线程编程模式(7)
- Java多线程设计模式-学习笔记-Thread Per Message模式.
- java多线程设计模式之Thread-Per-Message模式
- Java多线程设计模式详解学习笔记九——Thread-Per-Message
- POSIX线程-Per-Thread Storage
- 多线程服务器模型-one loop per thread
- WCF Note10(Message Pattern)
- windows, thread ,message queue
- Worker Thread Pattern
- Thread-Specific Storage Pattern
- android thread Handler 、Looper、 Message、 Message Queue
- [Design Pattern] Thread Local Session Pattern
- 读取xml文件转换为json文件
- 华为HBase性能调优
- 快速排序-C语言实现
- Android混合开发之——WebView页面栈遇上重定向
- JavaScript停止冒泡和阻止浏览器默认行为
- Thread-Per-Message Pattern
- 操作系统实验3
- PHP的几种排序算法的比较
- Spring Reactor 线程调度
- Halide学习笔记----Halide tutorial源码阅读2
- TCP的三次握手和四次挥手
- VS2013下新建静态库
- 【LeetCode】481. Magical String
- 2017hdu新生赛 1004 正品的概率