java多线程 异常处理_Java8多线程ForkJoinPool:处理异常
java多線程 異常處理
引入Java8 lambda背后的主要?jiǎng)訖C(jī)之一是能夠盡可能輕松地使用多核的能力(請(qǐng)參閱精通Lambdas:多核世界中的Java編程 )。 只需將代碼從collection.stream()...更改為collection.parallelStream()...您就可以使用即時(shí)多線程,從而為您的計(jì)算機(jī)帶來(lái)所有CPU功能。 (在這一點(diǎn)上,讓我們忽略爭(zhēng)用。)
如果打印出parallelStream使用的線程的名稱,您會(huì)注意到它們與ForkJoin框架使用的線程相同,如下所示:
請(qǐng)參閱本杰明·溫特伯格的博客 ,以獲取一個(gè)很好的示例。
現(xiàn)在,在Java 8中,您可以將這個(gè)commonPool直接與ForkJoinPool commonPool()上的新方法一起使用。 這將返回帶有commonPool線程的ForkJoinPool實(shí)例(這是一個(gè)ExecutorService)-與parallelStream中使用的線程相同。 這意味著您直接使用commonPool進(jìn)行的任何工作都可以與parallelStream中完成的工作很好地配合,尤其是線程調(diào)度和線程之間的竊取。
讓我們來(lái)看一個(gè)如何使用ForkJoin的示例,尤其是在處理棘手的異常主題時(shí)。
首先通過(guò)調(diào)用ForkJoin.commonPool()獲得commonPool的實(shí)例。 您可以使用submit()方法向其提交任務(wù)。 因?yàn)槲覀兪褂玫氖荍ava8,所以我們可以傳入lambda表達(dá)式,這確實(shí)很不錯(cuò)。 與所有ExecutorService實(shí)現(xiàn)一樣,您可以將Runnable或Callable實(shí)例傳遞到submit() 。 當(dāng)您將lambda傳遞到Submit方法時(shí),它將通過(guò)檢查方法簽名將其自動(dòng)轉(zhuǎn)換為Runnable或Callable 。
這導(dǎo)致一個(gè)有趣的問(wèn)題,突出了lambda如何工作。 假設(shè)您有一個(gè)返回類型為void的方法(如Runnable),但拋出了一個(gè)已檢查的異常(如Callable)。 參見方法throwException()
在下面的代碼清單中可以找到這樣的例子。 如果您編寫此代碼,它將無(wú)法編譯。
這樣做的原因是,由于void返回類型,編譯器假定您正在嘗試創(chuàng)建Runnable。 當(dāng)然,Runnable不能拋出異常。 要解決此問(wèn)題,您需要強(qiáng)制編譯器了解您正在創(chuàng)建一個(gè)Callable,使用該代碼技巧可以允許拋出Exception。
Future task1 = commonPool.submit(() -> {throwException("task 1");return null;});這有點(diǎn)混亂,但是可以完成工作。 可以說(shuō),編譯器本來(lái)可以解決這個(gè)問(wèn)題。
下面的完整代碼清單中還有兩點(diǎn)要強(qiáng)調(diào)。 第一,使用commonPool.getParallelism()可以看到池中有多少個(gè)線程可用。 可以使用參數(shù)'-Djava.util.concurrent.ForkJoinPool.common.parallelism'進(jìn)行調(diào)整。 第二,注意如何解開ExecutionException,以便您的代碼可以向其調(diào)用者呈現(xiàn)IOException而不是非特定的ExecutionException。 另請(qǐng)注意,此代碼在第一個(gè)異常時(shí)失敗。 如果要收集所有異常,則必須適當(dāng)?shù)貥?gòu)造代碼,可能會(huì)返回一個(gè)異常列表。 或者,可以更整潔地引發(fā)包含基礎(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
java多線程 異常處理
總結(jié)
以上是生活随笔為你收集整理的java多线程 异常处理_Java8多线程ForkJoinPool:处理异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 人员投标备案流程(人员投标备案)
- 下一篇: oracle中悲观锁定_如何使用悲观锁定