日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java8多线程ForkJoinPool:处理异常

發(fā)布時間:2023/12/3 java 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java8多线程ForkJoinPool:处理异常 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引入Java8 lambda背后的主要動機之一是能夠盡可能輕松地使用多核的能力(請參閱精通Lambdas:多核世界中的Java編程 )。 只需將代碼從collection.stream()...更改為collection.parallelStream()...您就可以使用即時多線程,從而為您的計算機帶來所有CPU功能。 (在這一點上,讓我們忽略爭用。)

如果打印出parallelStream所使用的線程的名稱,您會注意到它們與ForkJoin框架所使用的線程相同,如下所示:

[ForkJoinPool.commonPool-worker-1] [ForkJoinPool.commonPool-worker-2]

請參閱本杰明·溫特伯格的博客 ,以獲取一個很好的示例。

現(xiàn)在,在Java 8中,您可以將這個commonPool與ForkJoinPool commonPool()上的新方法直接一起使用。 這將返回帶有commonPool線程的ForkJoinPool(這是一個ExecutorService)實例–與parallelStream中使用的線程相同。 這意味著您直接使用commonPool進行的任何工作都可以與parallelStream中完成的工作很好地配合,尤其是線程調(diào)度和線程之間的竊取。

讓我們來看一個如何使用ForkJoin的示例,尤其是在處理棘手的異常主題時。

首先,通過調(diào)用ForkJoin.commonPool()獲得commonPool的實例。 您可以使用submit()方法向其提交任務(wù)。 因為我們使用的是Java8,所以我們可以傳入lambda表達式,這確實很不錯。 與所有ExecutorService實現(xiàn)一樣,您可以將Runnable或Callable實例傳遞給Runnable submit() 。 當您將lambda傳遞給Submit方法時,它將通過檢查方法簽名將其自動轉(zhuǎn)換為Runnable或Callable 。

這導(dǎo)致一個有趣的問題,突出了lambda如何工作。 假設(shè)您有一個返回類型為void的方法(如Runnable),但拋出了一個已檢查的異常(如Callable)。 參見方法throwException()
在下面的代碼清單中可以找到這樣的例子。 如果您編寫此代碼,它將無法編譯。

Future task1 = commonPool.submit(() -> {throwException("task 1");});

這樣做的原因是,由于void返回類型,編譯器假定您正在嘗試創(chuàng)建Runnable。 當然,Runnable不能拋出異常。 要解決此問題,您需要強制編譯器了解您正在創(chuàng)建一個Callable,使用此代碼技巧可以允許拋出Exception。

Future task1 = commonPool.submit(() -> {throwException("task 1");return null;});

這有點混亂,但可以完成工作。 可以說,編譯器本來可以解決這個問題。

下面的完整代碼清單中還有兩點要強調(diào)。 第一,您可以使用commonPool.getParallelism()看到池中有多少個線程可用。 可以使用參數(shù)'-Djava.util.concurrent.ForkJoinPool.common.parallelism'進行調(diào)整。 第二,注意如何解開ExecutionException,以便您的代碼僅向其調(diào)用者顯示IOException,而不是非特定的ExecutionException。 另請注意,此代碼在第一個異常時失敗。 如果要收集所有異常,則必須適當?shù)貥?gòu)造代碼,可能會返回異常列表。 或者更巧妙地拋出一個包含基礎(chǔ)異常列表的自定義異常。

public class ForkJoinTest {public void run() throws IOException{ForkJoinPool commonPool = ForkJoinPool.commonPool();Future task1 = commonPool.submit(() -> {throwException("task 1");return null;});Future task2 = commonPool.submit(() -> {throwException("task 2");return null;});System.out.println("Do something while tasks being " +"executed on " + commonPool.getParallelism()+ " threads");try {//wait on the result from task2task2.get();//wait on the result from task1task1.get();} catch (InterruptedException e) {throw new AssertionError(e);} catch (ExecutionException e) {Throwable innerException = e.getCause();if (innerException instanceof RuntimeException) {innerException = innerException.getCause();if(innerException instanceof IOException){throw (IOException) innerException;}}throw new AssertionError(e);}}public void throwException(String message) throws IOException,InterruptedException {Thread.sleep(100);System.out.println(Thread.currentThread() + " throwing IOException");throw new IOException("Throw exception for " + message);}public static void main(String[] args) throws IOException{new ForkJoinTest().run();} }

翻譯自: https://www.javacodegeeks.com/2015/02/java8-multi-threading-forkjoinpool-dealing-with-exceptions.html

總結(jié)

以上是生活随笔為你收集整理的Java8多线程ForkJoinPool:处理异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。