范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Callable和Future

  Callable
  Callable与Runnable的功能大致相似,Callable中有一个call()函数, 但是call()函数有返回值 ,而Runnable的run()函数不能将结果返回给客户程序。Callable的声明如下 :
  @FunctionalInterface public interface Callable {     /**      * Computes a result, or throws an exception if unable to do so.      *      * @return computed result      * @throws Exception if unable to compute a result      */     V call() throws Exception; }
  可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型,且该接口往往与Future结合使用。 Future
  package java.util.concurrent;  public interface Future {    boolean cancel(boolean mayInterruptIfRunning);     boolean isCancelled();     boolean isDone();     V get() throws InterruptedException, ExecutionException;     V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
  关于Future,源码中的注释如下:
  Future表示异步计算的结果。 提供了检查计算是否完成、等待其完成以及检索计算结果的方法。 结果只能在计算完成后使用方法get检索,必要时阻塞,直到它准备好。 取消是通过cancel方法执行的。 提供了额外的方法来确定任务是正常完成还是被取消。 一旦计算完成,就不能取消计算。 如果您想使用Future来取消可取消性但不提供可用的结果,您可以声明Future<?>形式的类型并返回null作为底层任务的结果。不难猜测该类的作用是异步进程计算结果。下面我们来看看它是如何工作的,话不多说我们以源码的研究之旅。cancel(boolean)
  尝试取消此任务的执行。 如果任务已完成、已被取消或由于某些其他原因无法取消,则此尝试将失败。 如果成功,并且在调用cancel时此任务尚未启动,则此任务不应该运行。 如果任务已经开始,则根据传入的参数确定是否应该中断执行该任务的线程以尝试停止该任务。
  此方法返回后,对isDone的后续调用将始终返回true 。 如果此方法返回true ,则对isCancelled的后续调用将始终返回true 。isDone()
  如果此任务完成,则返回true 。 完成可能是由于正常终止、异常或取消——在所有这些情况下,此方法都将返回true 。get()
  等待计算完成,获取结果。get(long timeout,TimeUnit unit)
  在给定时间范围内等待计算完成,获取结果。超过时间还未计算完成将抛出timeout异常。
  下面我们来来看看Future一个常用的实现类FutureTask。
  FutureTask类实现RunnableFuture接口,RunnableFuture接口继承Runnable和Future接口。到这里我们嗅到了一丝线程的味道,接着往下看。
  FutureTask对于任务运行的状态使用volatile关键字去修饰保证了线程的安全性,至于volatile关键字为何能保证线程安全后续文章解答。
  同时定义了0、1、2、3、4、5、6七个连续大小的整型变量来表示任务的状态变化,具体代码如下:
  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;
  FutureTask成员变量
  /** The underlying callable; nulled out after running */     private Callable callable;     /** The result to return or exception to throw from get() */     private Object outcome; // non-volatile, protected by state reads/writes     /** The thread running the callable; CASed during run() */     private volatile Thread runner;     /** Treiber stack of waiting threads */     private volatile WaitNode waiters;
  Callable callable
  将要执行的任务
  Object outcome
  Object类型,表示通过get()方法获取到的结果数据或者异常信息。
  volatile Thread runner
  运行Callable的线程,运行期间会使用CAS保证线程安全,这里大家只需要知道CAS是Java保证线程安全的一种方式, 后续文章中会深度分析CAS如何保证线程安全。
  volatile WaitNode waiters
  WaitNode是一个静态内部类,表示等待线程的堆栈中的链表节点,在FutureTask的实现中,会通过CAS结合此堆栈交换任务的运行状 态。
  WaitNode的定义如下:
  static final class WaitNode {         volatile Thread thread;         volatile WaitNode next;         WaitNode() { thread = Thread.currentThread(); }     }
  类中定义了一个Thread成员变量和指向下一个WaitNode节点的引用。其中 通过构造方法将thread变量设置为当前线程。
  FutureTask构造方法
  FutureTask(Callable callable)
  接收一个Callable变量,同时设置任务状态为NEW
  public FutureTask(Callable callable) {         if (callable == null)             throw new NullPointerException();         this.callable = callable;         this.state = NEW;       // ensure visibility of callable     }
  FutureTask(Runnable runnable, V result)
  接受一个Runnable线程变量以及返回结果类型,同时设置任务状态为NEW
  public FutureTask(Runnable runnable, V result) {         this.callable = Executors.callable(runnable, result);         this.state = NEW;       // ensure visibility of callable     }
  run
  public void run() {         if (state != NEW ||             !UNSAFE.compareAndSwapObject(this, runnerOffset,                                          null, Thread.currentThread()))             return;         try {             Callable c = callable;             if (c != null && state == NEW) {                 V result;                 boolean ran;                 try {                     result = c.call();                     ran = true;                 } catch (Throwable ex) {                     result = null;                     ran = false;                     setException(ex);                 }                 if (ran)                     set(result);             }         } finally {             // runner must be non-null until state is settled to             // prevent concurrent calls to run()             runner = null;             // state must be re-read after nulling runner to prevent             // leaked interrupts             int s = state;             if (s >= INTERRUPTING)                 handlePossibleCancellationInterrupt(s);         }     }
  如果任务状态state不等于NEW则直接return。如果state等于NEW,则调用UNSAFE.compareAndSwapObject方法执行CAS算法判断当前对象与当前线程是否一致,不一致则直接return。
  如果当前任务不等于null且状态等于NEW,则执行call方法同时调用set方法设置返回结果。最后将当前运行线程runner设置为null,如果任务状态>=INTERRUPTING会执行handlePossibleCancellationInterrupt方法将状态为INTERRUPTING的任务线程设置为就绪状态,但该任务线程不会被CPU再次执行调度。因为state没有被重置。
  handlePossibleCancellationInterrupt方法
  private void handlePossibleCancellationInterrupt(int s) {         // It is possible for our interrupter to stall before getting a         // chance to interrupt us.  Let"s spin-wait patiently.         if (s == INTERRUPTING)             while (state == INTERRUPTING)                 Thread.yield(); // wait out pending interrupt          // assert state == INTERRUPTED;          // We want to clear any interrupt we may have received from         // cancel(true).  However, it is permissible to use interrupts         // as an independent mechanism for a task to communicate with         // its caller, and there is no way to clear only the         // cancellation interrupt.         //         // Thread.interrupted();     }
  set(V v)
  protected void set(V v) {         if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {             outcome = v;             UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state             finishCompletion();         }     }
  CAS算法计算NEW偏移一个变量是否等于COMPLETING(2),是则将返回结果复制给outcome成员变量,同时设置stateOffset=NORMAL(2)为正常状态。
  最后调用finishCompletion()方法。
  finishCompletion()
  private void finishCompletion() {         // assert state > COMPLETING;         for (WaitNode q; (q = waiters) != null;) {             if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {                 for (;;) {                     Thread t = q.thread;                     if (t != null) {                         q.thread = null;                         LockSupport.unpark(t);                     }                     WaitNode next = q.next;                     if (next == null)                         break;                     q.next = null; // unlink to help gc                     q = next;                 }                 break;             }         }          done();          callable = null;        // to reduce footprint     }
  在finishCompletion()方法中,首先定义一个for循环,循环终止因子为waiters为null,在循环中,判断CAS操作是否成功,如果成功 进行if条件中的逻辑。首先,定义一个for自旋循环,在自旋循环体中,唤醒WaitNode堆栈中的线程,使其运行完成。当WaitNode 堆栈中的线程运行完成后,通过break退出外层for循环。接下来调用done()方法。
  done()
  默认实现什么也不做,子类可以覆盖此方法以调用完成回调。
  get()
  public V get() throws InterruptedException, ExecutionException {         int s = state;         if (s <= COMPLETING)             s = awaitDone(false, 0L);         return report(s);     }
  判断任务状态是否运行中,如果是调用awaitDone()方法等待任务完成。否则调用report方法返回结果。
  report(int s)
  private V report(int s) throws ExecutionException {         Object x = outcome;         if (s == NORMAL)             return (V)x;         if (s >= CANCELLED)             throw new CancellationException();         throw new ExecutionException((Throwable)x);     }
  如果任务状态等于NORMAL(3)则返回正常计算结果。如果任务状态大于等于CANCELLED(4)则返回异常结果。
  看到这里我们大致对Callable和Future的源码有了大致的了解。但是对于它们二者是怎么与多线程关联的,我们在下一个章节讲解

L2级展开最后较量!城市领航辅助终于来了,哪家实力足够强?说起人机交互,似乎我们总能联想到科幻电影里的飞天车与太空船,就好比电影回到未来里马丁开着DMC12穿越到30年后(2015年),看见悬浮滑板飞行汽车自动驾驶等高新科技。回到现实世界520礼物推荐奇遇DreamProVR,用实力展现全能王者风范因为疫情常态化的大背景,去游乐场和影院的次数和时间越来越少,相对应的,家人看手机和平板等电子产品的时间越来越多,导致身体状态越来越差,娱乐的生活也是日益乏味。为了解决这个问题,加之免费在线的数据库建模工具,云版PownerDesignerTeamDesigner团队协作,一款免费在线的数据库表设计工具。类似PownerDesigner的功能,可用于设计mysql,oracle的表结构。支持私有化部署地址http10苹果公司的市值跌到全球第二,市值第一原来是一家石油公司截止5月11日美股收盘,苹果公司下跌5。18,蒸发近1300亿美元(折合人民币约8700亿元),市值为2。37万亿美元(折合人民币约16万亿元)。当日,在沙特利雅得证券交易所上市的中国联通正式升级发布银龄专享服务计划来源中国青年报客户端中国青年报客户端北京5月17日电(中青报中青网记者宁迪)5月17日,是一年一度的世界电信和信息社会日,国际电信联盟将本年度世界电信和信息社会日主题确定为面向老年微软计划将薪酬预算增加近一倍微软周一表示,它将其工资预算增加近一倍并将股票范围扩大至少25。因为它希望在与其他科技公司竞争人才的同时,奖励其应对通胀上升的劳动力。在彭博社获得的一份声明中,总部位于华盛顿雷德蒙抖音电商推出商家复产护航计划,九项举措助力商家复工复产5月15日,抖音电商启动商家复产护航计划,投入25亿流量补贴超2亿元消费券补贴,面向受疫情影响的商家,在政策扶持平台活动物流扶持客服专线四个方面推出九项帮扶举措,保障消费者权益和体蔚来没有退路,荣耀是它的胜利之路吗?如果不是那场蓄谋已久的阴谋,相信华为的手机业务板块,依旧会交出一份十分强势的成绩单。战略层面,华为本品牌主打高端,直面对抗苹果三星NOVA继续以明星代言人和线下扩张的路线,对抗OP荣耀X205G手机66W快充8GB128GB,作为老人机还是很不错随着手机科技的快速发展,手机更新换代时间也越来越快,有些曾经辉煌一时的5G手机,很多如今却被沦为老人机了。以前买的老人机往往标配的运行内存和机身内存都比较低,大部分的千元机运行内存国内手机出货量暴跌,荣耀首次登顶,华为的曙光已现昨天,中国信通院公布了今年第一季度国内手机市场的出货量数据,总体出货量为6934。6万部,同比下降29。2,暴跌近三成。在这样的行情下,却出现了一颗璀璨又耀眼的明星,那就是荣耀手机motoedgeS30冠军版体验报告全面出色的性价比王者谈起摩托罗拉,伴随着Hellomoto的开机铃声,成为了一代人的深刻记忆。如今,在竞争日益白热化的国产智能手机市场中,消费者在享受移动通信飞速发展便利的同时,对手机从设计硬件体验诸
美的顶侧双吸集成灶LS5,用科技之光点亮健康烹饪新厨房厨房,承载着平淡时光里的人间烟火。煎炒蒸烤炸,端起人间美味的同时,大多数人对于厨房的需求也在不断升级,智能集成化无烟化成为构建厨房新生态的关键。美的厨电作为行业的头部品牌,顺应市场不晚于2030年实现100绿色电力,腾讯如何实现这一目标?21世纪经济报道记者曹恩惠上海报道近日,腾讯发布碳中和目标及行动路线报告,承诺不晚于2030年,实现自身运营及供应链的全面碳中和。同时,不晚于2030年,实现100绿色电力。报告附中科飞测闯关科创板股东背后浮现华为中芯国际等巨头身影,报告期内扣非净利润持续为负每经记者陈晴每经编辑魏官红半导体质量控制设备生产商深圳中科飞测科技股份有限公司(以下简称中科飞测)拟冲刺科创板上市。中科飞测的客户涉及中芯国际长江存储等多家知名集成电路企业,股东背中央一号文件第十八项快递进村,农村的年轻人有福了估计不少的网友看到我这样的一个标题,会觉得我对于某种事物认识的狭隘。为什么是农村的快递业务,适合农村的年轻人。原因有城市的生活经历又有农村的生活经历,它告诉我。农村的快递业,如今算原来苹果的土味文案另有玄机?论起苹果的品牌调性,很多人可能会说高端精致,不仅是因为它的前沿技术,还因为它简约精巧的设计风格。当然,苹果为了传达自己的品牌理念,也拍过很多脍炙人口的广告。比如早期的1984thi研究显示恐龙时代或于远古某春季开启末世新华社北京2月25日电参考消息25日登载美国科学新闻双周刊网站报道恐龙时代可能是在春季结束的。报道摘要如下大约6600万年前,一颗直径达10公里的小行星撞上地球。不久后,所有非鸟类几天不扫的家里有多脏?预算少的扫拖一体机,进入舒适的懒人生活文江湖独白专栏家里的卫生问题一直都是交给扫地机器人的,它真正让人感觉到舒适的生活,特别是在忙完回家不想动手时,这种幸福感爆棚的。对于忙碌一天的我们来说,家务是最琐碎的事情,为了家庭王清宪与杨杰举行工作会谈中安在线中安新闻客户端讯2月25日上午,省长王清宪与中国移动通信集团有限公司董事长杨杰一行举行工作会谈。副省长何树山参加。王清宪指出,当前,伴随着信息技术特别是5G技术的广泛应用,除了微信和qq,现在的年轻人最喜欢用的社交软件有哪些?1。陌陌多年来在努力洗白的陌陌。社交功能比较丰富,玩法比较多。2。探探真正的始于颜值。3。soul早期是一款灵魂交友的软件,很像是以前交笔友一样,比较纯。早期的用户群体主要是被软件用了五年华为手机,今天才知道这2个功能!简直会议记录神器使用那么久,华为手机上竟然还有这两个功能是我没用过的。这两个功能非常适合经常开会的朋友,只因为它能够帮助你节省一大半的时间,更加便捷地完成会议记录。我们日常开会时都会拿上一个笔记本终于有人把ampampquot计算机组成原理学习笔记ampampquot整理出来了1。计算机组成原理概论计算机数字电子计算机组成计算机硬件系统的逻辑实现原理不以具体机型为依托的,基本实现原理。计算机组成原理掌握如何实现的具体细节。1。1计算机系统简介计算机系统由