再次提出有關ArrayList和同步的問題。ArrayList,線程和同步 - 如何準確同步多個線程
我只是想知道這是什麼片斷究竟:
ArrayList<ObjectX> list = ....;
synchronized (list) {
if (list.contains(objectxy) == false) {
list.add(objectxy);
}
}
Ive得到了充滿ObjectXs一個ArrayList中。我想添加一個元素到列表中,但只有當列表不包含相同的元素。我之前(在另一種方法中)檢查列表是否包含對象 - 結果是否定的。但是有可能兩個線程同時認爲結果是否定的,並且他們都嘗試添加objectxy。 (還有其他一些必須在中間做的事情,這就是爲什麼我不能同步整個過程)
所以,在過程之後,當現在的線程來到上面的片段,我想防止這兩個都添加該對象到列表中。所以我想當我同步訪問列表時,只有一個線程可以檢查它是否包含對象,然後添加它。在它之後,第二個線程可以訪問列表,查看該對象已經在其中並且不再添加它。
那就是我想要達到的。 它會工作嗎? :-)
所以,如果是的話,我想知道片段到底是什麼。是否阻止兩個線程同時訪問此確切的代碼?這樣代碼只能同時用於一個線程?
或者它鎖定列表本身整個時間,在應用程序的任何線程是誰在這個時候嘗試訪問列表 - 隨時隨地? (我沒有其他的add()在我的代碼中,但許多gets(),這就是爲什麼Id喜歡知道其他線程是否可以訪問列表,並仍然獲取元素,而另一個線程訪問上面的代碼)。
ArrayList本身是一個使用應用程序與主體連接的成員變量。多個不同的線程同時訪問上面的代碼是正確的如果它們不是從相同的主體發送的,那麼正確的?
所以,這就是Id想知道的。我試圖標記我的問題,以便更容易地回答它們。感謝您的幫助! :-)
[編輯]謝謝你所有的答案,這幾乎所有的說法都一樣!我認爲現在很清楚! :-)
- 同步代碼塊只能由其中一個主體線程訪問。 (其他校長的線索與特殊校長無關)。該列表本身可以隨時從其他線程訪問 - 只要對它的訪問不與同步塊同步即可。如果是這樣,線程必須等待,直到它可以訪問列表(這意味着沒有其他線程同時在同步塊中)
是否正確?我希望如此:-)
感謝您的回答。我不使用synchronizedList,因爲我對它有非常少的操作需要同步 - 這就是爲什麼我認爲這是沒有必要的。由於CopyOnWriteArrayList也是線程安全的,我認爲這對我的應用程序來說也太多了 - 我實際上並不需要在每個點都進行同步。 :-) – nano7 2011-05-27 10:16:56
這種方法要非常小心:您必須確保*每個*列表訪問都不會與任何其他訪問重疊。例如,如果有一個線程執行get()而另一個執行同步(list){add()/ set()}指令的機會,您必須*同步get()指令。 – Flavio 2011-05-27 10:27:18
爲什麼?如果僅僅因爲用戶可以獲得不是最新的數據(可能缺少一個添加),那麼這並不重要 - 至少不適用於我的應用程序,我的意思是:-)我可以接受那個 – nano7 2011-05-27 12:01:38