目录
Java的两种异常
ForkJoinTask异常相关的主要方法
案例説明
一、主程序
二、分治任务
三、执行结果
在分治任务中,指定部分任务抛出异常。在主程序中,判断任务是否出现异常,并打印异常。
package xyz.jangle.thread.test.n5_5.exception;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
/**
* 5.5、在任务中抛出异常
* isCompletedAbnormally(),任务或子任务是否抛出异常。
* getException()获取抛出的异常。
* @author jangle
* @email [email protected]
* @time 2020年8月29日 下午5:58:32
*
*/
public class M {
public static void main(String[] args) {
int[] array = new int[100];
Task task = new Task(array, 0, 100);
ForkJoinPool pool = new ForkJoinPool();
pool.execute(task);
pool.shutdown();
try {
pool.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(task.isCompletedAbnormally()) {
System.out.println("Main:存在异常");
System.out.println("Main:"+task.getException());
}
// 任务中如果抛出非受检异常join方法会抛出RuntimeException异常。
System.out.println("Main:结果:"+task.join());
/*
* try { // 任务中如果抛出非受检异常get方法会抛出ExecutionException异常。
* System.out.println("Main:结果:"+task.get()); } catch (InterruptedException |
* ExecutionException e) { e.printStackTrace(); }
*/
}
}
package xyz.jangle.thread.test.n5_5.exception;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
/**
* @author jangle
* @email [email protected]
* @time 2020年8月29日 下午5:59:22
*
*/
public class Task extends RecursiveTask {
/**
*
*/
private static final long serialVersionUID = 1L;
private int array[];
private int start, end;
public Task(int[] array, int start, int end) {
super();
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
System.out.println("Task:开始执行从" + start + "到" + end);
if (end - start < 10) {
if (start < 3 && end > 3) {
throw new RuntimeException("这个任务抛出了一个异常,任务下标从" + start + "到" + end);
// 也可以使用这种方式抛出异常
// completeExceptionally(new Exception("这个任务抛出了一个异常,任务下标从" + start + "到" + end));
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
int mid = (end+start)/2;
Task task = new Task(array, start, mid);
Task task2 = new Task(array, mid, end);
invokeAll(task, task2);
System.out.println("Task:"+start+"--"+mid+":"+task.join());
System.out.println("Task:"+mid+"--"+end+":"+task2.join());
}
System.out.println("Task:"+start+"--"+end+":结束");
return 0;
}
}
Task:开始执行从0到100
Task:开始执行从0到50
Task:开始执行从0到25
Task:开始执行从50到100
Task:开始执行从0到12
Task:开始执行从75到100
Task:开始执行从50到75
Task:开始执行从12到25
Task:开始执行从6到12
Task:开始执行从25到50
Task:开始执行从87到100
Task:开始执行从75到87
Task:开始执行从75到81
Task:开始执行从87到93
Task:开始执行从25到37
Task:开始执行从25到31
Task:开始执行从62到75
Task:开始执行从12到18
Task:开始执行从0到6
Task:开始执行从50到62
Task:开始执行从62到68
Task:开始执行从50到56
Task:6--12:结束
Task:开始执行从56到62
Task:0--6:结束
Task:12--18:结束
Task:75--81:结束
Task:87--93:结束
Task:25--31:结束
Task:开始执行从31到37
Task:开始执行从93到100
Task:62--68:结束
Task:50--56:结束
Task:开始执行从68到75
Task:开始执行从18到25
Task:开始执行从81到87
Task:56--62:结束
Task:开始执行从37到50
Task:开始执行从37到43
Task:50--56:0
Task:56--62:0
Task:50--62:结束
Task:93--100:结束
Task:68--75:结束
Task:62--68:0
Task:18--25:结束
Task:12--18:0
Task:81--87:结束
Task:75--81:0
Task:18--25:0
Task:12--25:结束
Task:68--75:0
Task:62--75:结束
Task:87--93:0
Task:93--100:0
Task:87--100:结束
Task:31--37:结束
Task:25--31:0
Task:50--62:0
Task:62--75:0
Task:81--87:0
Task:75--87:结束
Task:开始执行从43到50
Task:75--87:0
Task:50--75:结束
Task:31--37:0
Task:87--100:0
Task:75--100:结束
Task:25--37:结束
Task:50--75:0
Task:75--100:0
Task:50--100:结束
Task:37--43:结束
Task:43--50:结束
Task:37--43:0
Task:43--50:0
Task:37--50:结束
Task:25--37:0
Task:37--50:0
Task:25--50:结束
Main:存在异常
Main:java.lang.RuntimeException: java.lang.RuntimeException: java.lang.Exception: 这个任务抛出了一个异常,任务下标从0到6
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: java.lang.Exception: 这个任务抛出了一个异常,任务下标从0到6
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:600)
at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:678)
at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:722)
at xyz.jangle.thread.test.n5_5.exception.M.main(M.java:34)
Caused by: java.lang.RuntimeException: java.lang.Exception: 这个任务抛出了一个异常,任务下标从0到6
at java.base/java.util.concurrent.ForkJoinTask.completeExceptionally(ForkJoinTask.java:953)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:35)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:1)
at java.base/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:94)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408)
at java.base/java.util.concurrent.ForkJoinTask.invokeAll(ForkJoinTask.java:761)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:46)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:1)
at java.base/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:94)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408)
at java.base/java.util.concurrent.ForkJoinTask.invokeAll(ForkJoinTask.java:761)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:46)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:1)
at java.base/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:94)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408)
at java.base/java.util.concurrent.ForkJoinTask.invokeAll(ForkJoinTask.java:761)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:46)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:1)
at java.base/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:94)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408)
at java.base/java.util.concurrent.ForkJoinTask.invokeAll(ForkJoinTask.java:761)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:46)
at xyz.jangle.thread.test.n5_5.exception.Task.compute(Task.java:1)
at java.base/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:94)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
Caused by: java.lang.Exception: 这个任务抛出了一个异常,任务下标从0到6
... 32 more