[英]Concurrent Execution: Future vs parallelstream
我編寫了一個可調用的函數來輪詢遠程客戶端以獲取信息,並以List形式返回該信息。 我正在使用threadpoolexecutor,for循環,以及Future與多個遠程客戶端並行執行任務。 然后我將所有Future列表與addAll()組合在一起,並使用巨型組合列表。
我的問題是,使用parallelstream()會比使用future和for循環更有效嗎? 編碼肯定更容易! 如果我走那條路,我會不再需要threadpoolexecutor?
謝謝!
for(SiteInfo site : active_sites) {
TAG_SCANNER scanr = new TAG_SCANNER(site, loggr);
Future<List<TagInfo>> result = threadmaker.submit(scanr);
//SOUND THE ALARMS
try {
alarm_tags.addAll(result.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
可能的解決方案代 Netbeans在這些方面提出了一些建議
active_sites.parallelstream().map((site) -> new TAG_SCANNER(site, loggr)).map((scanr) -> threadmaker.submit(scanr)).forEach((result) -> {
//SOUND THE ALARMS
try {
alarm_tags.addAll(result.get());
}
catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
這里有幾個誤解。 首先,如果在提交任務后立即調用Future.get
,則使用異步任務不會提高資源利用率,在提交下一個任務之前立即等待其完成。
其次,Netbeans進行的代碼轉換產生了一個大致相同的代碼,仍然向Executor
提交任務,所以它不是“Future vs parallelstream”的問題,因為你只是使用並行流執行提交(和等待)並仍然使用遺囑執行人。 由於你的第一個錯誤,並行執行可能會提高吞吐量,但除此之外,將兩個錯誤結合起來讓它們自行取消並不是一個好主意,它仍然是一個糟糕的解決方案:
Stream API的標准實現針對CPU綁定任務進行了優化,創建了許多與CPU核心數匹配的線程,並且當這些線程在等待操作中被阻塞時不生成新線程。 因此,使用並行流執行I / O操作,或者通常可以等待的操作,不是一個好的選擇。 而且您無法控制實現使用的線程。
更好的選擇是使用ExecutorService
,您可以根據預期的遠程客戶端I / O帶寬進行配置。 但是你應該在提交后立即修復等待的錯誤,首先提交所有任務,然后等待所有任務完成。 請注意,您可以使用流API,而不是為了更好的並行性,但可能會提高可讀性:
// first, submit all tasks, assuming "threadmaker" is an ExecutorService
List<Future<List<TagInfo>>> futures=threadmaker.invokeAll(
active_sites.stream()
.map(site -> new TAG_SCANNER(site, loggr))
.collect(Collectors.toList())
);
// now fetch all results
for(Future<List<TagInfo>> result: futures) {
//SOUND THE ALARMS
try {
alarm_tags.addAll(result.get());
} catch (InterruptedException | ExecutionException e) {
// not a recommended way of handling
// but I keep your code here for simplicity
e.printStackTrace();
}
}
請注意,此處使用的流API是順序的 ,僅用於將SiteInfo
列表轉換為Callable<List<TagInfo>>
,但您可以使用循環執行相同操作。
一般來說parallelstream
已經寫的非常聰明的程序員非常有效地做並行處理。
有了它,就像所有其他java線程一樣,例如並發包,那么除非你是這個主題的專家,否則如果你自己編寫它你可能會:
換句話說: 是的,使用parallelstream 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.