并发编程:fork/join框架:取消一个任务

39 篇文章 0 订阅
9 篇文章 0 订阅

目录

 

forkJoinTask.cancel()

案例说明

一、主程序

二、数组工厂

三、查找的任务类

四、任务管理类

五、执行结果


forkJoinTask.cancel()

我们可以在任务执行前取消任务。如果任务已经开始执行,那么调用cancel()方法就没有意义。其参数mayInterruptIfRunning的参数并未实现。

案例说明

创建一个数组,用分治法对指定数字进行查找,若一个任务找到,则取消其他所有任务。

一、主程序

package xyz.jangle.thread.test.n5_6.cancel;

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

/**
 * 5.6、取消一个任务
 *     创建一个数组,用分治法对指定数字进行查找,若一个任务找到,则取消其他所有任务。
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月30日 下午5:55:19
 * 
 */
public class M {

	public static void main(String[] args) {
		
		ArrayGenerator generator = new ArrayGenerator();
		int[] array = generator.generateArray(1000);
		TaskManager manager = new TaskManager();
		ForkJoinPool pool = new ForkJoinPool();
		SearchNumberTask searchNumberTask = new SearchNumberTask(array, 0, 1000, 6, manager);
		pool.execute(searchNumberTask);
		pool.shutdown();
		try {
			pool.awaitTermination(1, TimeUnit.DAYS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Main:主程序執行結束");

	}

}

二、数组工厂

package xyz.jangle.thread.test.n5_6.cancel;

import java.util.Random;

/**
 * 	生成一个数字数组
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月30日 下午5:55:51
 * 
 */
public class ArrayGenerator {

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

}

三、查找的任务类

package xyz.jangle.thread.test.n5_6.cancel;

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

/**
 * 查找的任务
 * 
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月30日 下午6:26:04
 * 
 */
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.println("Task:" + start + ":" + end);
		int ret;
		if (end - start > 10) {
			// 分割
			ret = launchTasks();
		} else {
			// 执行
			ret = lookForNumber();
		}
		return ret;
	}

	/**
	 * 执行查找,找到后取消所有其他任务。
	 * 
	 * @author jangle
	 * @time 2020年8月30日 下午6:38:47
	 * @return
	 */
	private int lookForNumber() {
		for (int i = start; i < end; i++) {
			if (numbers[i] == number) {
				System.out.println("Task:number找到了,下标为" + i);
				manager.cancelTasks(this);
				return i;
			}
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return NOT_FOUND;
	}

	/**
	 * 进行分治
	 * 
	 * @return
	 */
	private int launchTasks() {
		int mid = (start + end) / 2;
		SearchNumberTask task = new SearchNumberTask(numbers, start, mid, number, manager);
		SearchNumberTask task2 = new SearchNumberTask(numbers, mid, end, number, manager);
		manager.addTask(task);
		manager.addTask(task2);
		task.fork();
		task2.fork();
		int returnValue;
		returnValue = task.join();
		if (returnValue != -1) {
			return returnValue;
		} else {
			return task2.join();
		}
	}

	/**
	 * 取消任务时的日志信息
	 */
	public void logCancelMessage() {
		System.out.println("Task:取消了下标从" + start + "到" + end + "的任务");
	}

}

四、任务管理类

package xyz.jangle.thread.test.n5_6.cancel;

/**
 *   取消任务的管理类
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月30日 下午5:59:04
 * 
 */

import java.util.concurrent.ConcurrentLinkedDeque;

public class TaskManager {

	private final ConcurrentLinkedDeque<SearchNumberTask> tasks;

	public TaskManager() {
		tasks = new ConcurrentLinkedDeque<SearchNumberTask>();
	}

	public void addTask(SearchNumberTask task) {
		tasks.add(task);
	}

	public void cancelTasks(SearchNumberTask searchNumberTask) {
		for (SearchNumberTask forkJoinTask : tasks) {
			if (forkJoinTask != searchNumberTask) {
				forkJoinTask.cancel(true);
				forkJoinTask.logCancelMessage();
			}
		}

	}

}

五、执行结果

Task:0:1000
Task:500:1000
Task:0:500
Task:500:750
Task:500:625
Task:625:750
Task:0:250
Task:500:562
Task:250:500
Task:750:1000
Task:500:531
Task:750:875
Task:500:515
Task:562:625
Task:125:250
Task:0:125
Task:625:687
Task:0:62
Task:125:187
Task:0:31
Task:562:593
Task:500:507
Task:750:812
Task:250:375
Task:750:781
Task:562:577
Task:0:15
Task:125:156
Task:625:656
Task:125:140
Task:0:7
Task:562:569
Task:750:765
Task:250:312
Task:750:757
Task:number找到了,下标为562
Task:125:132
Task:625:640
Task:250:281
Task:625:632
Task:250:265
Task:250:257
Task:取消了下标从0到500的任务
Task:取消了下标从500到1000的任务
Task:取消了下标从500到750的任务
Task:取消了下标从750到1000的任务
Task:取消了下标从0到250的任务
Task:取消了下标从250到500的任务
Task:取消了下标从500到625的任务
Task:取消了下标从625到750的任务
Task:取消了下标从500到562的任务
Task:取消了下标从562到625的任务
Task:取消了下标从625到687的任务
Task:取消了下标从687到750的任务
Task:取消了下标从0到125的任务
Task:取消了下标从125到250的任务
Task:375:500
Task:取消了下标从500到531的任务
Task:375:437
Task:取消了下标从531到562的任务
Task:375:406
Task:取消了下标从250到375的任务
Task:375:390
Task:取消了下标从375到500的任务
Task:375:382
Task:取消了下标从750到875的任务
Task:取消了下标从875到1000的任务
Task:取消了下标从500到515的任务
Task:取消了下标从515到531的任务
Task:取消了下标从750到812的任务
Task:取消了下标从812到875的任务
Task:取消了下标从500到507的任务
Task:取消了下标从507到515的任务
Task:取消了下标从562到593的任务
Task:取消了下标从593到625的任务
Task:取消了下标从125到187的任务
Task:取消了下标从187到250的任务
Task:取消了下标从0到62的任务
Task:取消了下标从62到125的任务
Task:取消了下标从625到656的任务
Task:取消了下标从656到687的任务
Task:取消了下标从0到31的任务
Task:取消了下标从31到62的任务
Task:取消了下标从125到156的任务
Task:取消了下标从156到187的任务
Task:取消了下标从0到15的任务
Task:取消了下标从15到31的任务
Task:取消了下标从562到577的任务
Task:取消了下标从577到593的任务
Task:取消了下标从750到781的任务
Task:取消了下标从781到812的任务
Task:取消了下标从250到312的任务
Task:取消了下标从312到375的任务
Task:取消了下标从750到765的任务
Task:取消了下标从765到781的任务
Task:取消了下标从569到577的任务
Task:取消了下标从0到7的任务
Task:取消了下标从7到15的任务
Task:取消了下标从125到140的任务
Task:取消了下标从140到156的任务
Task:取消了下标从625到640的任务
Task:取消了下标从640到656的任务
Task:取消了下标从125到132的任务
Task:取消了下标从132到140的任务
Task:取消了下标从750到757的任务
Task:取消了下标从757到765的任务
Task:取消了下标从250到281的任务
Task:取消了下标从281到312的任务
Task:取消了下标从625到632的任务
Task:取消了下标从632到640的任务
Task:取消了下标从250到265的任务
Task:取消了下标从265到281的任务
Task:取消了下标从250到257的任务
Task:取消了下标从257到265的任务
Task:取消了下标从375到437的任务
Task:取消了下标从437到500的任务
Task:取消了下标从375到406的任务
Task:取消了下标从406到437的任务
Task:取消了下标从375到390的任务
Task:取消了下标从390到406的任务
Task:取消了下标从375到382的任务
Task:取消了下标从382到390的任务
Task:number找到了,下标为755
Task:取消了下标从0到500的任务
Task:取消了下标从500到1000的任务
Task:取消了下标从500到750的任务
Task:取消了下标从750到1000的任务
Task:取消了下标从0到250的任务
Task:取消了下标从250到500的任务
Task:取消了下标从500到625的任务
Task:取消了下标从625到750的任务
Task:取消了下标从500到562的任务
Task:取消了下标从562到625的任务
Task:取消了下标从625到687的任务
Task:取消了下标从687到750的任务
Task:取消了下标从0到125的任务
Task:取消了下标从125到250的任务
Task:取消了下标从500到531的任务
Task:取消了下标从531到562的任务
Task:取消了下标从250到375的任务
Task:取消了下标从375到500的任务
Task:取消了下标从750到875的任务
Task:取消了下标从875到1000的任务
Task:取消了下标从500到515的任务
Task:取消了下标从515到531的任务
Task:取消了下标从750到812的任务
Task:取消了下标从812到875的任务
Task:取消了下标从500到507的任务
Task:取消了下标从507到515的任务
Task:取消了下标从562到593的任务
Task:取消了下标从593到625的任务
Task:取消了下标从125到187的任务
Task:取消了下标从187到250的任务
Task:取消了下标从0到62的任务
Task:取消了下标从62到125的任务
Task:取消了下标从625到656的任务
Task:取消了下标从656到687的任务
Task:取消了下标从0到31的任务
Task:取消了下标从31到62的任务
Task:取消了下标从125到156的任务
Task:取消了下标从156到187的任务
Task:取消了下标从0到15的任务
Task:取消了下标从15到31的任务
Task:取消了下标从562到577的任务
Task:取消了下标从577到593的任务
Task:取消了下标从750到781的任务
Task:取消了下标从781到812的任务
Task:取消了下标从250到312的任务
Task:取消了下标从312到375的任务
Task:取消了下标从750到765的任务
Task:取消了下标从765到781的任务
Task:取消了下标从562到569的任务
Task:取消了下标从569到577的任务
Task:取消了下标从0到7的任务
Task:取消了下标从7到15的任务
Task:取消了下标从125到140的任务
Task:取消了下标从140到156的任务
Task:取消了下标从625到640的任务
Task:取消了下标从640到656的任务
Task:取消了下标从125到132的任务
Task:取消了下标从132到140的任务
Task:取消了下标从757到765的任务
Task:取消了下标从250到281的任务
Task:取消了下标从281到312的任务
Task:取消了下标从625到632的任务
Task:取消了下标从632到640的任务
Task:取消了下标从250到265的任务
Task:取消了下标从265到281的任务
Task:取消了下标从250到257的任务
Task:取消了下标从257到265的任务
Task:取消了下标从375到437的任务
Task:取消了下标从437到500的任务
Task:取消了下标从375到406的任务
Task:取消了下标从406到437的任务
Task:取消了下标从375到390的任务
Task:取消了下标从390到406的任务
Task:取消了下标从375到382的任务
Task:取消了下标从382到390的任务
Task:number找到了,下标为131
Task:取消了下标从0到500的任务
Task:取消了下标从500到1000的任务
Task:取消了下标从500到750的任务
Task:取消了下标从750到1000的任务
Task:取消了下标从0到250的任务
Task:取消了下标从250到500的任务
Task:取消了下标从500到625的任务
Task:取消了下标从625到750的任务
Task:取消了下标从500到562的任务
Task:取消了下标从562到625的任务
Task:取消了下标从625到687的任务
Task:取消了下标从687到750的任务
Task:取消了下标从0到125的任务
Task:取消了下标从125到250的任务
Task:取消了下标从500到531的任务
Task:取消了下标从531到562的任务
Task:取消了下标从250到375的任务
Task:取消了下标从375到500的任务
Task:取消了下标从750到875的任务
Task:取消了下标从875到1000的任务
Task:取消了下标从500到515的任务
Task:取消了下标从515到531的任务
Task:取消了下标从750到812的任务
Task:取消了下标从812到875的任务
Task:取消了下标从500到507的任务
Task:取消了下标从507到515的任务
Task:取消了下标从562到593的任务
Task:取消了下标从593到625的任务
Task:取消了下标从125到187的任务
Task:取消了下标从187到250的任务
Task:取消了下标从0到62的任务
Task:取消了下标从62到125的任务
Task:取消了下标从625到656的任务
Task:取消了下标从656到687的任务
Task:取消了下标从0到31的任务
Task:取消了下标从31到62的任务
Task:取消了下标从125到156的任务
Task:取消了下标从156到187的任务
Task:取消了下标从0到15的任务
Task:取消了下标从15到31的任务
Task:取消了下标从562到577的任务
Task:取消了下标从577到593的任务
Task:取消了下标从750到781的任务
Task:取消了下标从781到812的任务
Task:取消了下标从250到312的任务
Task:取消了下标从312到375的任务
Task:取消了下标从750到765的任务
Task:取消了下标从765到781的任务
Task:取消了下标从562到569的任务
Task:取消了下标从569到577的任务
Task:取消了下标从0到7的任务
Task:取消了下标从7到15的任务
Task:取消了下标从125到140的任务
Task:取消了下标从140到156的任务
Task:取消了下标从625到640的任务
Task:取消了下标从640到656的任务
Task:取消了下标从132到140的任务
Task:取消了下标从750到757的任务
Task:取消了下标从757到765的任务
Task:取消了下标从250到281的任务
Task:取消了下标从281到312的任务
Task:取消了下标从625到632的任务
Task:取消了下标从632到640的任务
Task:取消了下标从250到265的任务
Task:取消了下标从265到281的任务
Task:取消了下标从250到257的任务
Task:取消了下标从257到265的任务
Task:取消了下标从375到437的任务
Task:取消了下标从437到500的任务
Task:取消了下标从375到406的任务
Task:取消了下标从406到437的任务
Task:取消了下标从375到390的任务
Task:取消了下标从390到406的任务
Task:取消了下标从375到382的任务
Task:取消了下标从382到390的任务
Main:主程序執行結束

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值