Thread-Per-Message Pattern

来源:互联网 发布:小米5如何备份数据 编辑:程序博客网 时间:2024/05/16 10:32

Thread-Per-MessagePattern

Per是“每一”的意思,Thread-Per-Message即每个消息一个线程。Message在这里可以看作是“命令”或“请求”的意思。对每个命令或请求,分配一个线程,由这个线程执行工作,这就是Thread-Per-Message Pattern

使用Thread-Per-Message Pattern时,“委托消息的一端”与“执行消息的一端”会是不同的线程。委托消息的线程将“消息”发送给执行消息的线程之后,无须等待返回结果,继续自己线程本身的任务。

例如,服务器端有一个线程不断的接受来自客户端(多个)的请求,对于每一个请求,服务器启动一个新的线程来处理这个请求,之后,线程继续接受客户端的请求,无须等待处理结果。

示例

客户端向服务器端发送多个请求,请求内容为要求服务器端将字符串data打印count次。

Main:测试程序

public class Main {

 

  public staticvoid sleep() {

      try {

         Thread.sleep(1000);

      } catch(InterruptedException e) {

         e.printStackTrace();

      }

  }

 

  public staticvoid main(String[] args) {

 

      // 创建服务器端实例

      Serverserver = new Server();

 

      // 创建多个客户端实例,向特定的服务器端实例发送请求

      Clientclient1 = new Client();

      client1.sendMessage("AAAAAAAAAAA",5, server);

 

      sleep();

 

      Clientclient2 = new Client();

      client2.sendMessage("BBB",10, server);

 

      sleep();

 

      Clientclient3 = new Client();

      client3.sendMessage("C%C%C",6, server);

 

  }

}

Client:模拟客户端向服务器端发送请求

public class Client {

 

  public voidsendMessage(String data, int count, Server server) {

      //模拟服务器端接收到来自客户端的请求

      server.receiveMessage(data,count);

  }

 

}

Server:模拟服务器端接收用户请求

import java.util.Date;

 

public class Server {

 

  public voidreceiveMessage(String data, int count) {

      //对于每一个来自客户端的请求,服务器端均启动一个新的线程处理请求

      newHandleMessage(data, count, new Date().toString()).start();

  }

 

}

HandleMessage:处理用户请求

public class HandleMessage extends Thread {

 

  privateString data;

 

  private intcount;

 

  publicHandleMessage(String data, int count, String threadName) {

      super(threadName);

 

      this.data= data;

      this.count= count;

  }

 

  @Override

  public voidrun() {

      //处理请求:将数据打印特定次数

      try {

         for(int i = 0; i < count; i++) {

             Thread.sleep(500);

             System.out.println(Thread.currentThread().getName()+ " : "

                    +data);

         }

      } catch(InterruptedException e) {

         e.printStackTrace();

      }

  }

}

思考

提升响应性,降低延迟时间

使用Thread-Per-Message PatternServerClient的响应性会提高,延迟时间会下降。尤其是当HandleMessage的操作很花时间时,或是HandleMessage的操作需要等待I/O时,效果特别明显。

使用Thread-Per-Message Pattern时,在Server里会启动新的线程。因为启动线程需要花一定的时间,所以对希望用来提升响应性的Thread-Per-Message Pattern而言,“处理请求所需要花的时间”与“启动线程所需要花的时间”是鱼与熊掌不能兼得的关系。

为了降低启动线程所需的时间,可以使用线程池。

适合在操作顺序无所谓时使用

Thread-Per-MessagePattern中,服务器启动新的线程处理请求的方法的执行顺序,并不一定是客户端发送请求的顺序。所以操作顺序有意义时,不适合使用该模式。

不需要返回值的时候

Thread-Per-MessagePattern中,接收请求的方法不会等待处理请求的方法执行结束。也就是说,接收请求的方法得不到处理请求方法的返回值。所以,该模式只能在不需要返回值的情况下使用。例如,通知事件的发生等等。

服务器应用

为了使服务器可以处理多数的请求,可以使用Thread-Per-Message Pattern。客户端送达的请求,由主线程来接收。而实际处理该请求,则交给其他线程负责,服务器的主线程回到继续等待其他客户端请求的状态。