2013-03-18 84 views
1

我正在製作一個分配任務的程序。我有溝通對象的ArrayList像這樣:如何在java中以線程安全方式創建迭代器循環

ArrayList<Workers> 

我通過文件工作我的方式,將其劃分爲固定大小的塊和分派到各個工人。我正在使用迭代器來均勻地將塊傳遞給工作人員。通常比工人更多的塊,所以我需要在我的工人周圍和周圍循環。我如何做到這一點,我現在的解決方案使用像這樣的迭代器。

private Worker getNextWorker() { 
    if (workerIterator == null) 
     workerIterator = workers.iterator(); 

    if (!workerIterator.hasNext()) 
     workerIterator = workers.iterator(); 

    return workerIterator.next(); 
} 

我同步的方法,以及這些方法修改的ArrayList但是,這並不使之安全作爲另一個線程可以進來和修改迭代器調用之間的集合。因此,我同步整個文件分割過程,使其成爲一個大的原子語句。

1)我錯過了什麼嗎?

2)是否有另一個,也許更好的方式,我可以這個循環功能。

+2

你可能會更好地讓工人承擔任務,而不是將任務交給工人。也就是說,JDK中有幾種可用於此類事情的解決方案:Executors和ExecutorService,CompletionService ... – 2013-03-18 22:35:37

+0

爲什麼不使用ExecutorService? – 2013-03-18 22:39:49

+0

問題在於我所處理的文件很大,我分裂成大塊的原因是爲了避免內存問題。然而,如果我能以某種方式限制工作池的規模,並且阻止更多的工作直到工人拿出一些東西,這將是完美的。這可能嗎? – 2013-03-18 23:13:34

回答

1

您可以啓動工作者線程(不含執行程序),並從有界的阻塞隊列中獲取元素take。讀取文件時,您在隊列中輸入put塊。當隊列已滿時,對put的調用將阻塞,直到工作人員從隊列中取出一個任務。如果隊列爲空,則工作人員將等待,直到任務放入隊列中。當您完成處理時,您可以使用工作線程interrupt

或者,您可以將ThreadPoolExecutorbounded blocking queueCallerRunsPolicy一起使用。這樣,如果隊列未滿,任務將被提交執行。如果隊列已滿,則調用者線程將執行該任務(這給了工作人員處理的時間)。使用這種方法,最多隻能有number_of_threads+queue_capacity塊,但在主線程正在處理時,某些工作線程可能處於空閒狀態。

+0

謝謝你的回答是清晰並且有幫助 – 2013-03-18 23:39:10

2

我建議你不要重新發明輪子,並使用BlockingQueueThreadPoolExecutor結合用於此目的。

+0

謝謝你將看到這個,我想這必須存在 – 2013-03-18 22:52:17

+0

我將如何使用阻塞隊列來實現這一點,我可以想到的一種方式是讓工作人員在隊列中,我拿出一個,閱讀文件的塊,發送,然後將該工作人員放在隊列的後面。它不是真的如何設計模式,但它可能工作? – 2013-03-18 23:09:54

+0

您應該將文件塊放入隊列並通過Executor處理它們。 [關於阻塞隊列和執行程序的文章](http://howtodoinjava.com/2012/10/20/how-to-use-blockingqueue-and-threadpoolexecutor-in-java/) – 2013-03-18 23:12:32