java 并行_在使用Java并行流之前要三思而后行
如果您聽Oracle的人談?wù)揓ava
背后的設(shè)計(jì)選擇,您會(huì)經(jīng)常聽到并行是主要?jiǎng)訖C(jī)。并行化是lambda,流API和其他背后的驅(qū)動(dòng)力。讓我們看一下流API的示例。
private long countPrimes(int max) {
return range(1, max).parallel().filter(this::isPrime).count();
}
private boolean isPrime(long n) {
return n > 1 && rangeClosed(2, (long) sqrt(n)).noneMatch(divisor -> n % divisor == 0);
在這里,我們有一種方法 countPrimes 可以計(jì)算介于1和最大值之間的質(zhì)數(shù)。通過范圍方法創(chuàng)建數(shù)字流。然后將流切換到并行模式。不是質(zhì)數(shù)的數(shù)字將被過濾掉,剩余的數(shù)字將被計(jì)數(shù)。
您會(huì)看到流API使我們能夠以簡潔明了的方式描述問題。而且,并行化只是調(diào)用該 parallel() 方法的問題。當(dāng)我們這樣做時(shí),流被分成多個(gè)塊,每個(gè)塊被獨(dú)立處理,并在最后匯總結(jié)果。由于我們對(duì)該isPrime 方法的實(shí)現(xiàn) 效率極低且占用大量CPU,因此我們可以利用并行化的優(yōu)勢并利用所有可用的CPU內(nèi)核。
讓我們看另一個(gè)例子:
private List getStockInfo(Stream symbols) {
return symbols.parallel()
.map(this::getStockInfo) //slow network operation
.collect(toList());
我們在輸入中列出了股票代號(hào)列表,我們必須調(diào)用慢速網(wǎng)絡(luò)操作來獲取有關(guān)股票的一些詳細(xì)信息。在這里,我們不處理CPU密集型操作,但是我們也可以利用并行化。并行執(zhí)行多個(gè)網(wǎng)絡(luò)請(qǐng)求是一個(gè)好主意。同樣,對(duì)于并行流來說這是一項(xiàng)不錯(cuò)的任務(wù),您是否同意?
如果這樣做,請(qǐng)?jiān)俅尾榭辞懊娴氖纠S袀€(gè)大錯(cuò)誤。你看到了嗎?問題在于,所有并行流都使用公共的fork-join線程池,并且,如果您提交長時(shí)間運(yùn)行的任務(wù),則可以有效地阻塞池中的所有線程。因此,您將阻止所有其他使用并行流的任務(wù)。想象一下一個(gè)servlet環(huán)境,其中一個(gè)請(qǐng)求調(diào)用getStockInfo() 而另一個(gè)請(qǐng)求調(diào)用 countPrimes()。一個(gè)將阻止另一個(gè),即使它們每個(gè)都需要不同的資源。更糟糕的是,您無法為并行流指定線程池;整個(gè)類加載器必須使用相同的加載器。
讓我們在以下示例中對(duì)其進(jìn)行說明:
private void run() throws InterruptedException { ExecutorService es = Executors.newCachedThreadPool(); // Simulating
在這里,我們模擬系統(tǒng)中的六個(gè)線程。他們所有人都在執(zhí)行CPU密集型任務(wù),第一個(gè)被“破壞”并在找到質(zhì)數(shù)后立即睡眠一秒鐘。這只是一個(gè)人為的例子。您可以想象一個(gè)線程被卡住或執(zhí)行阻塞操作。
問題是:執(zhí)行此代碼會(huì)發(fā)生什么?我們有六個(gè)任務(wù);其中之一將需要一整天才能完成,其余的要早得多。毫不奇怪,每次執(zhí)行代碼時(shí),都會(huì)得到不同的結(jié)果。有時(shí),所有健康的任務(wù)都會(huì)完成;其他時(shí)間,其中一些滯后于緩慢的時(shí)間。您是否希望在生產(chǎn)系統(tǒng)中有這種行為?一項(xiàng)破碎的任務(wù)使其他應(yīng)用程序癱瘓了嗎?我猜不是。
如何確保這種事情永遠(yuǎn)不會(huì)發(fā)生只有兩種選擇。首先是確保提交到公共fork-join池的所有任務(wù)不會(huì)卡住并在合理的時(shí)間內(nèi)完成。但這說起來容易做起來難,尤其是在復(fù)雜的應(yīng)用程序中。另一個(gè)選擇是不使用并行流,等到Oracle允許我們指定要用于并行流的線程池。
最后,開發(fā)這么多年我也總結(jié)了一套學(xué)習(xí)Java的資料與面試題,如果你在技術(shù)上面想提升自己的話,可以關(guān)注我,私信發(fā)送領(lǐng)取資料或者在評(píng)論區(qū)留下自己的聯(lián)系方式,有時(shí)間記得幫我點(diǎn)下轉(zhuǎn)發(fā)讓跟多的人看到哦。
總結(jié)
以上是生活随笔為你收集整理的java 并行_在使用Java并行流之前要三思而后行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenJudge NOI 1.7 26
- 下一篇: php开发工程师考试试卷,腾讯PHP开发