future task cancel
1 FutureTask.cancel 干了啥
//有一个入参,需要说明task是否是可中断的
public boolean cancel(boolean mayInterruptIfRunning) {
if (state != NEW)
return false;
if (mayInterruptIfRunning) {
//尝试修改futuretask的运行状态
if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
return false;
//获取当前线程发出中断信号
Thread t = runner;
if (t != null)
t.interrupt();
//修改task装态为已中断的
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
}
//如果是不可中断的只修改task的状态为cancelled
else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
return false;
//执行finishCompletion方法
/**
* Removes and signals all waiting threads, invokes done(),and nulls out callable.
*/
finishCompletion();
return true;
}
跑完了 返回false
没跑完,输入true,修改为Interrupting,中断t,修改为Interrupted,返回true
没跑完,输入false,修改为Cancelled,返回true
compareAndSwapInt 相等并赋值成功返回true,否则返回false
2 FutureTask.cancel与Thread.interrupt区别
package multithreadci;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* Created by mac on 2023/9/4.
*/
public class TestCancel {
public static void main(String []f ) {
FutureTask subTask = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
Thread.sleep(100000);
return true;
}
});
Thread threadSubTask = new Thread(subTask);
threadSubTask.start();
FutureTask parentTask = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
try {
Object res = subTask.get();
System.out.print(res);
} catch (InterruptedException e) {
e.printStackTrace(); // 2
} catch (ExecutionException e) {
e.printStackTrace(); // 3
} catch (CancellationException e) {
e.printStackTrace(); // 1
// }
//
// try {
// subTask.get();
// } catch (Exception e) {
// e.printStackTrace();
}
return true;
}
});
Thread threadParentTask = new Thread(parentTask);
threadParentTask.start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 有对.get所在线程inturrupt之后,总是抛Interrupted而不是Cancellation
* 因为get中part唤醒后第一个就是判断是否被中断,根本走不到return和后面的report Cancellatioln
* 如果出现Cancellation,一定没有对.get所在线程interrupt或所在future cancel
*/
int cc = 5;
switch (cc) {
// 仅对subtask的thread interrupt
case 1: // 进3
threadSubTask.interrupt();
break;
// 仅对subtask cancel,不涉及对parent thread的interrupt
case 2: // 进1
subTask.cancel(true);
break;
// 涉及对parent thread的interrupt
case 3: // 进1
subTask.cancel(true);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
parentTask.cancel(true);
break;
case 4: // 进2
subTask.cancel(true);
parentTask.cancel(true);
break;
case 5: // 进2
parentTask.cancel(true);
subTask.cancel(true);
break;
}
}
}).start();
}
}
3
package com.jds.test.httpproxy;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class TestCancel {
public static void main(String []f){
FutureTask childTask = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
Thread.sleep(100000);
return true;
}
});
Thread threadSubTask = new Thread(childTask, "mock child task");
threadSubTask.start();
FutureTask parentTask = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
try {
Object res = childTask.get();
System.out.print(res);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
// } catch (CancellationException e) {
// e.printStackTrace();
// Thread.currentThread().interrupt();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
if(Thread.currentThread().isInterrupted()) {
System.out.println("quit");
} else {
System.out.println("I'm still running, hahaha, come to stop me");
}
return true;
}
});
Thread threadParentTask = new Thread(parentTask, "mock parent task");
threadParentTask.start();
Timer timer = new Timer("mock ecore's cancelling task action");
timer.schedule(new TimerTask() {
@Override
public void run() {
childTask.cancel(true);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
parentTask.cancel(true);
}
}, 5000);
}
}
java.util.concurrent.CancellationException
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:121)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at com.jds.test.httpproxy.TestCancel$2.call(TestCancel.java:28)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:834)
I'm still running, hahaha, come to stop me
浙公网安备 33010602011771号