簡體   English   中英

在這種情況下,同步語句如何工作?

[英]How does a synchronized statement work in this case?

假設我有一個這樣的課:

public class Server {

   public static void main(String[] args) {

      Map<Integer, ServerThread> registry = Collections.synchronizedMap(new LinkedHashMap<Integer, ServerThread>());

      ...

      while(true) {
         Socket socket = serverSocket.accept();
         ServerThread serverThread = new ServerThread(id, registry);
         registry.put(id, serverThread);
      }
   }
}

然后:

public class ServerThread extends Thread {

   private Map<Integer, ServerThread> registry;
   private int id;

   public ServerThread(int id, Map<Integer, ServerThread> registry) {
      this.id = id;
      this.registry = registry;
   }

   ...

   private void notify() {
      synchronized(registry) {
         for(ServerThread serverThread : registry.values()) {
            serverThread.callSomePublicMethodOnThread();
         }
      }      
   }
}

我只想確保在迭代registry不會對其進行修改。 使它成為同步映射是否可以保證這種行為? 還是我需要synchronized語句。 同步語句的行為是否會像我期望的那樣?

謝謝

您需要圍繞循環的synchronized塊。

有關詳細信息,請參見JavaDoc

是的,您擁有的同步語句將按預期工作。 我只想添加一條評論,您接受套接字連接的線程將在Registry.put(id,serverThread);上阻塞。 當您在另一個線程的同步部分中時。 這意味着您在處理通知時,服務器將不會處理任何新的傳入請求。

您可能需要考慮將put語句(當然將serverThread更改為該語句)移動到ServerThread的run方法的run方法的第一行。 這樣,如果callSomePublicMethodOnThread花費很長時間進行處理,您將不會阻止傳入的連接。

為了使一切變得更容易,我將使用ConcurrentHashMap(http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html),因此您無需使用sync塊在循環中,由於currentHashMap使用其他類型的迭代器(不是快速失敗的迭代器),並且不會阻止currentupModificationException,因此您還將獲得更好的性能。

代碼中有一個問題,您不能將您的方法定義為“ private void notify()”,因為“ notify()”是在Object類中定義的方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM