多线程Java服务器与安全发布

时间:2010-10-03 21:58:33

标签: java multithreading concurrency

当你google for 多线程java服务器时,大多数时候你会得到一个基于以下模式的解决方案:

public class MultiThreadServer implements Runnable {
  private Socket socket;

  MultiThreadServer(Socket socket) {
    this.socket = socket;
  }

  public static void main(String args[]) throws Exception {
    ServerSocket serverSocket = new ServerSocket(4444);
    while (true) {
      new Thread(new MultiThreadServer(serverSocket.accept())).start();
    }
  }

  public void run() {
    // ...
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
                new InputStreamReader(
                socket.getInputStream()));
    // ...
  }
}

这与 Java Concurrency in Practice 中提供的安全发布习语有什么关系?

  

安全地发布对象,两者都是   引用对象和   必须使对象的状态可见   其他线程同时。一个   正确构造的对象可以   安全发布者:

     
      
  • 从中初始化对象引用   一个静态初始化器。
  •   
  • 存储a   将它引入一个易变的领域。
  •   
  • 将参考文献存入决赛   领域。
  •   
  • 存储对它的引用   一个受到适当保护的领域   (同步)锁。
  •   

在没有任何额外同步的情况下在socket方法中使用run()是否真的安全,它是否安全发布?请不要只写

1 个答案:

答案 0 :(得分:2)

是的,这是安全的,因为线程的开始定义了一个发生之前的关系。也就是说,MultiThreadServer构造函数调用执行线程的run方法之前发生。

来自Java Language Specification 17.4.4-17.4.5:

  

在启动线程

中的任何操作之前,对线程的start()调用发生

实践中的Java并发中的注意事项适用于其他现有线程可以访问对象的情况,因此它们不适用于这种情况。