2010-10-03 51 views
1

當谷歌多線程Java服務器,大部分的時間你會得到基於下面的模式解決方案:多線程Java服務器VS安全出版物

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併發實踐

要安全地發佈對象,無論是 參考對象和 對象的狀態必須在同一時間內看到其他 線程。甲 正確構造的對象可以是 安全的出版商:

  • 初始化從 靜態初始化一個對象引用。
  • 將 的引用存儲到易失性字段中。
  • 將參考存儲到最終的 字段中。
  • 將對其的引用存儲到 由 (同步)鎖適當保護的字段。

是不是真的安全run()方法中使用socket沒有任何額外的同步,是它安全地發佈?請不要只寫

回答

2

是的,這是安全的,因爲線程的開始定義了發生在之間的關係。也就是MultiThreadServer的構造函數調用發生在執行之前的線程的run方法。

Java Language Specification 17.4.4-17.4.5:

調用開始()上線之前發生在啓動線程的任何行動從Java併發

注意事項實踐適用於當其他現有線程可訪問對象的情況下,因此它們不適用於此情況。

+0

有道理,謝謝! – lukem00 2010-10-03 22:49:05

+0

這意味着如果線程是從線程池中取出的,而不是新的線程(),那麼它不會安全 - 或者我沒有正確地得到它? (在這種情況下,將'socket'字段標記爲final是否足夠?) – nos 2010-10-04 16:19:31

+0

@nos:'ExecutorService'在javadoc中顯式地提供了相同的保證:http://download.oracle.com/javase/6/docs/api/的java/util的/並行/ ExecutorService.html – axtavt 2010-10-04 16:25:48