1.概念
翻译过来就是每个消息一个线程。message可以理解为命令,请求。为每一个请求新分配一个线程,由这个线程来执行处理。
Thread-Per-Message模式中,请求的委托端和请求的执行端是不同的线程,请求的委托端会告诉请求的执行端线程:这项工作就交给你了
2.示例程序
(1)Host类:针对请求创建线程的类
(2)Helper类:执行端,实际进行请求的处理
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");
}
public void slowly(){
try {
Thread.sleep(100);
}catch (InterruptedException e){
}
}
}
public class Host {
private final Helper helper = new Helper();
/**
* requst方法不会等待handle方法执行结束,而是立即返回
* @param count
* @param c
*/
public void request(final int count, final char c){
System.out.println(" request)" +count + " ," +c +") begin");
//匿名内部类,创建一个新的线程去处理,该线程直接返回。
new Thread(){
@Override
public void run() {
helper.handle(count,c);
}
}.start();
System.out.println(" request)" +count + " ," +c +") end");
}
}
public class Test {
public static void main(String[] args) {
System.out.println("------BEGIN-----");
Host host = new Host();
host.request(10,'a');
host.request(20,'b');
host.request(30,'c');
System.out.println("------END-------");
}
}
3.模式特点
-
提高响应性,缩短延迟时间
当handle方法操作非常耗时的时候可以使用该模式。如果handle方法执行时间比创建一个新线程的时间还短,那就没必要了 -
操作顺序没有要求
handle方法并不一定是按照request方法的调用顺序来执行的
4.使用线程池改进
public class MessageHandler {
private final static Random random = new Random(System.currentTimeMillis());
private final static Executor executor = Executors.newFixedThreadPool(5);
public void request(Message message) {
executor.execute(() -> {
String value = message.getValue();
try {
Thread.sleep(random.nextInt(1000));
System.out.println("The message will be handle by " + Thread.currentThread().getName() + " " + value);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
public void shutdown() {
((ExecutorService) executor).shutdown();
}
}
public class Message {
private final String value;
public Message(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public class PerThreadClient {
public static void main(String[] args) {
final MessageHandler handler = new MessageHandler();
IntStream.rangeClosed(0, 10)
.forEach(
i -> handler.request(new Message(String.valueOf(i)))
);
handler.shutdown();
}
}