并发编程:fork/join框架:在任务中抛出异常

目录

Java的两种异常

ForkJoinTask异常相关的主要方法

案例説明

一、主程序

二、分治任务

三、执行结果


Java的两种异常

  • 受检异常:必须在方法声明中抛出或在方法内捕获,比如IOException和ClassNotFoundException。
  • 未受检异常:不必声明或捕获,如NumberFormatException。

ForkJoinTask异常相关的主要方法

  1. isCompletedAbnormally()方法,如果该任务或其子任务抛出异常,则方法返回true。
  2. getException()方法,获取抛出的异常。

案例説明

在分治任务中,指定部分任务抛出异常。在主程序中,判断任务是否出现异常,并打印异常。

一、主程序

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

 

你可能感兴趣的:(并发编程,#,JavaBase,#,Fork/Join,java,并发编程)