[英]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.