第五章 Fork/Join Framework(Fork/join 框架)【下】

本章涉及的内容:
  • 创建一个Fork/Join 池
  • 插入任务的结果
  • 同步运行任务
  • 在任务中抛出异常
  • 取消一个任务

1、在任务中抛出异常

package com.jack;

import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

public class Task extends RecursiveTask<Integer> {

	/**
	 * 
	 */
	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.printf("任务: 开始从%d 到 %d\n", start, end);
		if(end - start <10){
			if((3>start) && (3<end)){
				throw new RuntimeException("任务抛出一个异常从" + start+ "到" + end);
			}
			try {
				TimeUnit.SECONDS.sleep(1);
			}catch (InterruptedException e){
				e.printStackTrace();
			}
		} else {
			int mid = (end+start)/2;
			Task task1 = new Task(array, start, mid);
			Task task2 = new Task(array, mid , end);
			invokeAll(task1, task2);
		}
		System.out.printf("任务: 结束形式 %d 到 %d\n", start, end);
		return 0;
	}

	
}

package com.jack;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

public class Main {
	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.printf("Main: 一个异常已经抛出\n");
			System.out.printf("Main: %s\n", task.getException());
		}
		System.out.printf("Main: 结果:%d", task.join());
	}
}

总结:(执行过程)

  • 1、创建一个任务task(实现了RecursiveTask<T>接口。
  • 2、创建执行者。执行任务。关闭
  • 3、防止Main主线程退出
  • 4、获取异常

2、取消一个任务

以下两种情况需要考虑

1、ForkJoinPool类不会提供任何方法去取消正在运行或在池中等待的任务

2、当你取消一个任务的时候,你不能取消已经执行的任务。

package com.jack;

import java.util.Random;

public class ArrayGenerator {
	
	public int[] generateArray(int size){
		int array[] = new int[size];
		Random random = new Random();
		for(int i=0; i<size; i++){
			array[i] = random.nextInt(10);
		}
		return array;
	}
} 

总结:生成一个随机数组

package com.jack;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinTask;

public class TaskManager {

	private List<ForkJoinTask<Integer>> tasks;
	public TaskManager(){
		tasks = new ArrayList<>();
	}
	
	public void addTask(ForkJoinTask<Integer> task){
		tasks.add(task);
	}
	
	public void cancelTasks(ForkJoinTask<Integer> cancelTask){
		for(ForkJoinTask<Integer> task :tasks){
			if(task!=cancelTask){
				task.cancel(true);
				((SearchNumberTask) task).writeCancelMessage();
			}
		}
	}
}

总结:如果没有找数字就取消任务

package com.jack;

import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

public class SearchNumberTask  extends RecursiveTask<Integer>{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private int numbers[];
	private int start,end;
	private int number;
	private TaskManager manager;
	
	private final static int NOT_FOUND=-1;
	
	public SearchNumberTask(int[] numbers, int start, int end, int number, TaskManager manager) {
		super();
		this.numbers = numbers;
		this.start = start;
		this.end = end;
		this.number = number;
		this.manager = manager;
	}

	@Override
	protected Integer compute() {
		System.out.printf("任务: %d : 结束\n" , start);
		int ret;
		if(end -start>10){
			ret = launchTasks();
		} else {
			ret = lookForNumber();
		}
		return ret;
	}

	private int lookForNumber() {
		for (int i=start; i<end; i++){
			if(numbers[i] == number) {
				System.out.printf("任务:数字 %d 找到 位置在%d\n", number, i);
				manager.cancelTasks(this);
				return i;
			}
			try{
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e){
				e.printStackTrace();
			}
		}
		return NOT_FOUND;
	}

	private int launchTasks() {
		int mid = (start+end)/2;
		SearchNumberTask task1 = new SearchNumberTask(numbers, start, mid, number, manager);
		SearchNumberTask task2 = new SearchNumberTask(numbers, mid,end, number, manager);
		manager.addTask(task1);
		manager.addTask(task2);
		task1.fork();
		task2.fork();
		int returnValue;
		returnValue = task1.join();
		if(returnValue!=-1){
			return returnValue;
		}
		returnValue = task1.join();
		return returnValue;
	}
	
	public void writeCancelMessage(){
		System.out.printf("任务: 取消任务 从%d 到 %d \n", start, end);
	}

}

查找数字,任务细分

package com.jack;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

public class Main {
	public static void main(String[] args) {
		ArrayGenerator generator = new ArrayGenerator();
		int array[] = generator.generateArray(1000);
		TaskManager manager = new TaskManager();
		ForkJoinPool pool = new ForkJoinPool();
		SearchNumberTask task = new SearchNumberTask(array, 0, 1000, 5, manager);
		pool.execute(task);
		pool.shutdown();
		try {
			pool.awaitTermination(1, TimeUnit.DAYS);
		} catch (InterruptedException e){
			e.printStackTrace();
		}
		System.out.printf("Main : 执行完毕\n");
	}
}

总结;

  • 1、生成一个数组
  • 2、创建任务管理来实现取消任务
  • 3、创建任务对象SearchNumberTask
  • 4、执行任务(如果没有找到数字的任务取消掉)
  • 5、关闭ForkJoinPool

日志:


第五章完。。。。。。。。。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值