Callable、Future和FutureTask的实现(4)

1、判断主线程是否被中断,如果被中断,将当前WaitNode节点从waiters链表中删除,并上抛InterruptedException
2、如果任务已经完成(可能是正常完成、异常、中断),直接返回(即还没有开始等待,任务已经完成了,就返回了)
3、如果任务正在完成,让出CPU资源,等待state变成NORMAL或EXCEPTIONAL
4、如果任务没有被中断,也没有完成,new WaitNode()
5、如果任务没有被中断,也没有完成,也创建了WaitNode,使用UNSAFE.CAS()操作将WaitNode加入waiters链表
6、所有准备工作完毕,通过LockSupport的park或parkNanos挂起线程

WaitNode就是一个简单的链表节点,记录这等待的线程和下一个WaitNode

/** * Simple linked list nodes to record waiting threads in a Treiber * stack. See other classes such as Phaser and SynchronousQueue * for more detailed explanation. */ static final class WaitNode { volatile Thread thread; //等待的线程 volatile WaitNode next; //下一个WaitNode WaitNode() { thread = Thread.currentThread(); } } FutureTask.cancel()的实现 public boolean cancel(boolean mayInterruptIfRunning) { if (state != NEW) return false; if (mayInterruptIfRunning) { if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING)) return false; Thread t = runner; if (t != null) t.interrupt(); //中断线程 UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state } else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED)) return false; finishCompletion(); return true; }

1、如果任务不是运行状态,直接返回false失败
2、如果mayInterruptIfRunning==true,中断运行中的任务,使用CAS操作将状态NEW-->INTERRUPTING,再调用runner.interrupt(),最后将状态置为INTERRUPTED
3、如果mayInterruptIfRunning==false,将任务置为CANCELLED取消状态
4、调用finishCompletion()依次唤醒等待获取结果的线程,返回true取消成功

四、使用示例 import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class TestFuture { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(1); Task task = new Task(); //callable任务 Future<Integer> result = executor.submit(task); executor.shutdown(); try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("主线程在执行任务"); try { System.out.println("task运行结果:"+result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("所有任务执行完毕"); } static class Task implements Callable<Integer>{ @Override public Integer call() throws Exception { System.out.println("子线程在进行计算"); Thread.sleep(3000); int sum = 0; for(int i=0;i<100;i++) sum += i; return sum; } } }

运行结果:

子线程在进行计算 主线程在执行任务 task运行结果:4950 所有任务执行完毕

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/874be636a1c974ddd6f7449a3e17fe1e.html