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(); } }