[英]Java: Create large number of Callables or distribute iterator result to threads?
我寫了一個操作圖像的應用程序。 我的操作代碼應該應用於文件夾中的所有圖像(每個文件夾最多1百萬個)。
到目前為止,對於文件夾中的每個圖像,我創建了一個Callable
(它是一個操縱圖像的工作者)並將其添加到ArrayList
。 然后我使用FixedThreadPool
的invokeAll
方法來並行化工作。
但是,我的問題是: 這個好設計嗎? 我有一些疑問,首先在數組列表中添加1百萬個元素真的很有意義。 我正在考慮將iterator
(通過文件)傳遞給所有線程並讓每個線程接受下一個元素並處理它(當然,不幸的是阻塞問題) - 但這有意義嗎?
我聽起來不錯,即使它不一定非常有效並且不能很好地擴展。 另一種設計可能是:
ArrayBlockingQueue<File>
(比如說大兩倍) FileVisitor
,我們稱之為ImageFileVisitor
,這在visitFile
方法puts
了訪問文件中的隊列-這是一個阻塞調用,因此將等到隊列不滿 Callable
S作為您的池的大小,使他們每個人的take
從隊列中,做他們必須做的事 注意:線程池的大小應該相當小。 如果您的圖像處理非常繁重,請使用大小的處理器數量,如果它有點微不足道並且大部分時間花在讀取/寫入文件上,請使用較小的大小。
FixedThreadPool
使用LinkedBlockingQueue
的Integer.MAX_VALUE
:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
所以,它的情感非阻塞,就像你能夠offer
/ put
百萬個Runnable
實例一樣,當然,這是為了保存數百萬個對象而不記得使用內存,盡管你的fixedPoolSize
相對要小得多,比如5/10。
直接改進這種情況的一種方法是使用具有有限隊列大小的FixedThreadPool
:
int nThreads = 10;
int maxQSize = 1000;
ExecutorService service = new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(maxQSize))
通過以上apporach,您的put
期權將阻止Q
1000
runnables,但只要其中一些完成, put
將繼續。 通過執行invokeAll
,將有10個正在運行的線程和最多1000個可運行的實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.