public class Main {
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");
}
}
public class Host {
private Helper helper = new Helper();
public void request(final int count, final char c) {
System.out.println(" Request(" + count + "," + c + ")Begin");
new Thread(new Runnable() {
@Override
public void run() {
helper.handle(count, c);
}
}).start();
System.out.println(" Request(" + count + "," + c + ")End");
}
}
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Main BeginRequest(10,A)Begin
Request(10,A)End
Request(20,B)Begin
Request(20,B)End
Request(30,C)Begin
Handle(10,A)Begin
Request(30,C)End
Main End
Handle(30,C)Begin
Handle(20,B)Begin
CBACBACABBCABACBACBCACBACABBA
Handle(10,A)End
CCBCBCBCBCBBCCBCBCBB
Handle(20,B)End
CCCCCCCCCCC
Handle(30,C)End
Thread-Per-Message解释过来就是“每个消息一个线程”,“消息委托的一端”和“执行消息的一端”会是不同的线程,也就是委托消息的线程对执行消息的线程说“这个工作交给你了”。
通过打印的信息会发现在handle方法结束前,request方法已经结束了。执行main方法的主线程,调用完host的request方法后,就马上结束了,送出“帮忙显示一下A呀”“帮忙显示一下B呀”“帮忙显示一下C呀”这些指示,自己就结束了。无论handle方法多花时间,都不会影响request方法的响应性。request方法不会等待handle方法执行完毕,而会马上退出。
提高响应性,降低延迟时间
使用Thread-Per-Message时,在Host参与者里面,会启动新的线程,因为启动线程需要花一些时间,所以对希望用来提升响应性的Thread-Per-Message Pattern而言,“handle的操作需要花的时间”与“启动线程需要花的时间”是鱼与熊掌不可兼得的关系。为了降低启动线程所花的时间可使用Worker Thread Pattern。Thread-Per-Message Pattern每次提出请求时启动一条线程,Worker Thread Pattern则预先启动足够数量的线程,重复使用这些线程,提升程序的执行性能。
使用的范围:
适合在操作顺序无所谓时使用
handle方法执行的顺序,并不一定是调用request方法的顺序。所以操作顺序有意义时,不适合使用Thread-Per-Message Pattern
不需要返回值的时候
Thread-Per-Message Pattern中,request方法不会等待handle方法执行结束,也就是说request方法拿不到handle方法的返回值。所以Thread-Per-Message Pattern只能在不需要返回值的时候使用,需要得知处理结果时可使用Future Pattern
应用在服务器的制作
为了使服务器可以处理多数的请求,可以使用Thread-Per-Message Pattern,客户端送达的请求,由主线程来接收。而实际处理该请求,则交给其他线程负责,服务器的主线程回到继续等待其他客户端请求的状态