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

来源:互联网 发布:58同城合肥找美工 编辑:程序博客网 时间:2024/06/06 10:49
本章涉及的内容:
  • 创建一个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;}@Overrideprotected 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;}@Overrideprotected 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

日志:


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

原创粉丝点击