react 前端框架如何驱动企业数字化转型与创新发展
583
2022-10-22
AQS同步组件-FutureTask解析和用例
FutureTask原理
源码分析
构造函数
public FutureTask(Callable
FutureTask新建提供两个构造方法来封装Callable和Runnable,当构造方法传入参数为Runnable,会通过Executors.callable方法将其转换成Callable。
常用方法
/** * 可能的状态转换:: * 新建 -> 已完成 -> 正常 * 新建 -> 已完成 -> 异常 * 新建 -> 已取消 * 新建 -> 中断ing -> 已中断 */ private volatile int state; private static final int NEW = 0; private static final int COMPLETING = 1; private static final int NORMAL = 2; private static final int EXCEPTIONAL = 3; private static final int CANCELLED = 4; private static final int INTERRUPTING = 5; private static final int INTERRUPTED = 6; boolean cancel(boolean mayInterruptIfRunning);//取消任务 boolean isCancelled();//是否被取消 boolean isDone();//计算是否完成 //get方法,获取执行结果,如果当前线程还没有执行完成, get方法会被阻塞。 public V get() //可以设置超时时间并获取执行结果,如果当前线程还没有执行完成, get方法会被阻塞。 public V get(long timeout, TimeUnit unit) /** * awaitDone方法其实是个死循环,直到task状态变为已完成状态或者等待时间超过 *超时时间或者线程中断才会跳出循环,程序结束; *为了节省开销,线程不会一直自旋等待,而是会阻塞,使用LockSupport的park系列方法实现线程阻塞 */ private int awaitDone(boolean timed, long nanos) throws InterruptedException { final long deadline = timed ? System.nanoTime() + nanos : 0L; WaitNode q = null; boolean queued = false; for (;;) { //如果线程中断,将当前线程从等待队列waiters中移除,抛出中断异常 if (Thread.interrupted()) { removeWaiter(q); throw new InterruptedException(); } int s = state; //如果线程已完成,设为null if (s > COMPLETING) { if (q != null) q.thread = null; return s; } //如果正在执行,让出cpu else if (s == COMPLETING) // cannot time out yet Thread.yield(); //如果节点为空,则初始化节点 else if (q == null) q = new WaitNode(); else if (!queued) //CAS queued = UNSAFE.compareAndSwapObject(this, waitersOffset, q.next = waiters, q); //超时将节点移除队列。否则阻塞到超时。 else if (timed) { nanos = deadline - System.nanoTime(); if (nanos <= 0L) { removeWaiter(q); return state; } LockSupport.parkNanos(this, nanos); } else //阻塞自己 LockSupport.park(this); } }
根据FutureTask的run方法执行的时机,FutureTask可以处于以下三种执行状态:
未启动:在FutureTask.run()还没执行之前,FutureTask处于未启动状态。当创建一个FutureTask对象,并且run()方法未执行之前,FutureTask处于未启动状态。 已启动:FutureTask对象的run方法启动并执行的过程中,FutureTask处于已启动状态。 已完成:FutureTask正常执行结束,或者FutureTask执行被取消(FutureTask对象cancel方法),或者FutureTask对象run方法执行抛出异常而导致中断而结束,FutureTask都处于已完成状态。
当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞
当FutureTask处于已完成状态时,执行FutureTask.get()方法将导致调用线程立即返回结果或抛出异常
当FutureTask处于未启动状态时,执行FutureTask.cancel()方法将导致此任务永远不会被执行
当FutureTask处于已启动状态时,执行FutureTask.cancel(true)方法将以中断执行此任务线程的方式来试图停止任务
当FutureTask处于已启动状态时,执行FutureTask.cancel(false)方法将不会对正在执行此任务的线程产生影响(让正在执行的任务运行完成)
当FutureTask处于已完成状态时,执行FutureTask.cancel(…)方法将返回false。
使用案例
FutureTask、Runnable、Callable
public static void main(String[] args) throws Exception {
FutureTask
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~