目录
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:主程序執行結束