我有一個集合,我想產生一些線程來做一些繁重的工作。集合中的每個元素都必須處理一次且只能處理一次。我想保持同步儘可能小,我想出了下面的代碼:這是多線程迭代安全嗎?
//getting the iterator is actually more complicated in my specific case
final Iterator it = myCollection.terator();
Thread[] threads = new Thread[numThreads];
for(int i = 0; i < numThreads; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
Object obj = null;
while(true) {
synchronized (it) {
if(it.hasNext())
obj = it.next();
else
return;
}
//Do stuff with obj
}
}
});
threads[i].start();
}
for (Thread t : threads)
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
注:沒有線程將永遠通過添加或刪除項目,而
「所有與obj做的東西」修改集合這段代碼與我在周圍發現的人們傾向於同步集合本身,使用Collection.synchronizedStuff..
,或者他們只是在整個迭代中同步的示例完全不同。在我的研究過程中,我還發現可能使用ThreadPoolExecutor
更好的替代方案,但讓我們暫時忘掉它...
考慮到上面的註釋1,代碼是否安全?如果不是,爲什麼?
只要注1仍然是真的,它會沒事的。執行者絕對是這樣的事情的途徑。 – BevynQ
如果您爲了性能原因試圖保持「同步」塊不變,那麼您可能會驚訝在每個(本地)線程的創建和執行過程中花費了多少時間,而是按照建議使用執行程序。 –
你的概念代碼看起來不錯。應該工作良好。訪問迭代器(包括檢查和讀取對象)是同步的,所以沒有問題。 – xagyg