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

多线程FutureTask执行流程

  在 Java 中可以用来创建线程的方式很多,比如由 Java 提供的 Thread、Runnable 等。本文章来介绍使用 FutureTask 创建线程,以及其流程。  Thread 和 Runnable 的问题
  众所周知,使用 Thread、Runnable 创建线程是非常方便的,只要实现 线程的 run 方法即可。但是通过 Thread、Runnable 实现 run 方法创建的线程是无法获取返回结果的,原因是线程方法 run 本身是没有返回值的。但是在很多场景中,我们是需要 异步执行的同时获取其线程执行的返回结果的。因此 Java 除了 Thread、Runnable 外,还提供了 FutureTask,它使得我们可以在异步执行的同时获取到线程的返回结果。
  本文就来介绍一下 FutureTask 类的简单使用。  FutureTask 介绍
  FutureTask 类本身不能用来创建线程,创建线程的工作仍然是由 Thread 类来创建的,FutureTask 和 Runnable 类似,是通过 Thread 类的构造方法传递给 Thread 类的。但是注意观察,Thread 类并没有一个构造方法是用于接受 FutureTask 类型的构造方法。  FutureTask 定义与继承关系
  那么,FutureTask 为什么可以传递给 Thread 类呢?这里重点不是看 Thread 类的构造方法,而是应该看一下 FutureTask 类的定义,该类的定义如下:  public class FutureTask implements RunnableFuture {
  可以看到,FutureTask 实现了 RunnableFuture 接口,那么继续看 RunnableFuture 接口的定义,该定义如下:  public interface RunnableFuture extends Runnable, Future {      void run();  }
  从 RunnableFuture 接口的定义可以看出,它继承了 Runnable 接口, 那么这样,就可以将 FutureTask 类以构造方法参数的形式传递给 Thread 类了。 在 RunnableFuture 接口中有一个 run 方法,那么这就要求实现 RunnableFuture 接口的类要去实现了 run() 方法。这样,FutureTask 类既然实现了 RunnableFuture 接口,那么 FutureTask 类中必然有一个 run 方法是供 Thread 类调用的。
  那么 RunnableFuture 继承的 Future 是什么呢?看一下它的定义,定义如下:  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 是一个泛型接口,通过 get() 方法可以阻塞等待获取异步计算的结果,也可以在获取异步计算结果的阻塞上设置一个超时时间。还可以通过 cancel() 方法设置让线程取消、使用 isCancelled() 方法判断线程是否被取消、以及通过 isDone() 方法判断线程是否执行完成。
  同样的 ,F uture 接口中的所有实现均在 FutureTask 中可以找到。
  总结一下,FutureTask 实现了 Runnable 接口的 run() 方法(该方法在 Thread.start() 后被调用),实现了 Future 的 get()、cancel()、isCancelled() 和 isDone() 方法。但是,get() 方法是从何处获取到线程的结果呢?这次来看一下 FutureTask 的 run() 方法吧。  FutureTask 实现的 run 方法分析
  FutureTask 实现了 RunnableFuture 接口,RunnableFuture 继承了 Runnable 接口,那么 FutureTask 则可以作为 Thread 类的构造方法的参数传递给 Thread 类,FutureTask 类实现的 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);      }  }
  从上面的代码中可以看出,Fut ureTask 的 run() 方法 是固定的, 并不能 在该 run 方法中实现我们自己的业务 代码,那应该如何完成自己的线程业务代码呢?来观察一下上面的代码。
  上面的代码中,主要看 try 块中的代码,在 第 7 行, 定义了 一个 C allable 的变量 c,在 第 9 行,定义了一个泛型的 result 变量 , 在第 12 行, 有一句 result = c.call(),在第 20 行有一句 set(result) 。我们分别来观察一下这基础。
  第 7 行代码如下:  Callable c = callable;
  第 7 行代码中的 callable 是 FutureTask 的属性,其定义如下:  private Callable callable;
  它是通过构造方法赋值得到的,FutureTask 的构造方法如下:  public FutureTask(Callable callable) {      if (callable == null)          throw new NullPointerException();      this.callable = callable;      this.state = NEW;       // ensure visibility of callable  }
  那么,我们在使用 FutureTask 时,会给它传递 Callable 来实例化它。接着看第 12 行代码,代码如下:  result = c.call()
  可以看出, Callable 有一个 call() 方法,并且有返回值,那么来看一下 Callable 的定义,它的定义如下:  @FunctionalInterface  public interface Callable {      V call() throws Exception;  }
  可以看到它是一个泛型接口,该接口中有一个方法 call(),它有返回值,且可以抛出异常。而这个 call() 方法,就是我们用来写自己业务的线程方法。然后这个方法在 FutureTask 的 run() 方法中被调用。那么返回值呢?同样从第 12 行代码可以看出,c.call() 后把返回值给到了 result 中,最后调用了第 20 行的代码,代码如下:  set(result)
  我们来查看 set() 方法做了什么,代码如下:  protected void set(V v) {      if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {          outcome = v;          UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state          finishCompletion();      }  }
  set() 方法将返回值赋值给了 outcome,outcome 也是 FutureTask 的属性,其定义如下:  private Object outcome;
  前面介绍过,get() 方法是用来获取返回结果的,我们通过观察 get() 方法来验证一下,代码如下:  @SuppressWarnings("unchecked")  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);  }     public V get() throws InterruptedException, ExecutionException {      int s = state;      if (s <= COMPLETING)          s = awaitDone(false, 0L);      return report(s);  }
  可以看到,get() 方法返回的就是实际的 outcome 这个属性。  FutureTask 实例
  来一个简单的例子,来看看 FutureTask 的使用,代码如下:  public class FutureTaskTest  {      static public class CallableThread implements Callable {          /**           * 此处的call方法是实际的线程方法,写我们的异步任务           * 这里是一个简单的计算100的累加和           */          @Override          public Integer call() throws Exception {              int sum = 0;                 for (int i = 1; i <= 100; i ++) {                  sum += i;              }                 return sum;          }      }         public static void main(String[] args) {          CallableThread callableThread = new CallableThread();          FutureTask integerFutureTask = new FutureTask<>(callableThread);             Thread thread = new Thread(integerFutureTask);          thread.start();          try {              // 这里通过FutureTask.get()方法来阻塞获取结算的结果              System.out.println(integerFutureTask.get());          } catch (InterruptedException | ExecutionException e) {              e.printStackTrace();          }      }  }
  上面的示例代码非常的简单,在线程任务中完成一个100内的累加和计算,然后在 main 线程中通过 FutureTask 的 get() 方法来阻塞的获取计算结果。  总结
  总结一下,使用 FutureTask 类时,要配合使用 Thread 类和 Callable 接口,刚开始看可能对三个类之间的关系有点乱,但是当实际的了解了 FutureTask 类的 run() 方法以后,其实整个脉络就清楚了。与 FutureTask 类相关的几个重要接口有 RunnableFuture、Runnable、Future,以及 Callable。能清楚的梳理好它们之间的关系,就可以相对清楚的明白 FutureTask 类了。
  希望本文对你有所帮助!喜欢可以点赞、分享!

一加10Pro评测游戏体验大突破,帧率最稳的骁龙8手机?刚发布的一加10PRO,真没料到一家旗舰居然这么快就来了,我提前收到了机器,满打满算用了十多天。说句实话,这次除了非常大胆的外观创新之外,一家识破的硬件参数确实没什么惊喜,所以发布P2E区块链游戏赚钱1hr什么是PlaytoEarn?Plantoearn的商业模式在传统游戏由来已久,魔兽世界阴阳师等游戏均有一批玩家通过出售装备或者装备赚钱。而在区块链游戏中,将这种模式进行了升级如果我家有个机器人现在,机器人可以说是全能的了,机器人什么都会干的,坐在那儿弹琴弹个不停,也不会出错,也不用休息,也不用吃饭睡觉,会炒菜的机器人,炒出的菜很标准,色香味美,丝毫不逊色人炒出来的,还有养老护理智能化!大小便智能护理机器人催生护理新模式科技改变生活随着人工智能在养老护理设备中的不断应用,让养老护理工作进入到了新阶段,使护理工作变得更便捷更高效更人性更科学更健康。通过引进作为科技大小便智能护理机器人这一新的智能新技售价10万的日本妻子机器人,除了生子什么都能做?小心别被骗日本专门为宅男打造了一款妻子机器人?据说她上得厅堂下得厨房,除了生孩子什么都会,能够很好地照顾主人。最重要的是,这样智能机器人竟然只售价10万元?消息一出全网哗然,不少网友表示请务为什么新浪的后台并发能力那么差?主要还是资金问题啊。为什么这么说?现在,各种技术架构都算已经比较成熟的情况下,并发其实很容易解决,就是扩容。简单理解就是加服务器和拆分服务。新浪微博流量具有瞬间峰值高持续时间短,这2022年2月最值得买的低价手机盘点,256GB顶配版本最低1399元2月随着三星S22系列的发布,新的一波发布会正在路上了,像刚过去的红米K50电竞版和红魔游戏手机,接下来还有OPPOFindX5系列手机,但是这次,咱们不选这些新机,刚发布太贵,我这手机的隐私保护能力是安卓的100倍,它到底什么来头?不知道大家对于2017年的Essential手机还有没有印象?这家由安卓系统创始人之一安迪鲁宾创立的公司,于2017年推出了EssentialPhonePH1之后,后续的产品并不足大学用iPadPro还是高配游戏本比较好?我根据我选购电脑和iPad的实际经历,一条条来给题主分析1大一会计专业,平常用电脑也就写个作文填填表格办公什么的。所以iPadPro基本上可以淘汰了因为无论是内置还是外置的键盘都不小米手机关闭广告后,整个世界清静了小米手机关闭广告该怎么做?现如今,小米手机可以说是国产之光,凭借性价比做高端机立足于国内,但是不足之处还是有很多的,远的不说,就说说广告吧!小米手机怎么关闭广告?对于小米手机的广告互联网第一梯队龙头公司集体布局东数西算工程华为云拥有贵安乌兰察布一南一北两大云数据中心,同时在京津冀长三角粤港澳地区布局了三大核心数据中心。阿里云在京津冀内蒙古等枢纽节点均有数据中心。腾讯正在建设西部云计算数据中心二期项目
荣耀X20SE首销倒计时1天!后置64MP三摄1799元起手机中国新闻日前,荣耀不动声色地推出了一款价格更友好的新机荣耀X20SE。这款手机采用四面窄边框设计,屏占比超高,后置竖排三摄像头,有幻夜黑蓝水翡翠钛空银樱粉金四种配色,看上去简单既然都是华为手机,为什么要分Mate类和p类到底区别在哪里这次想跟大家分享的是,为什么华为手机分为Mate和P两种手机,它们的区别在哪里?今天就和大家一一分析。首先,华为手机是国产的,知名度也非常高。同时,它们也是国产中高端智能手机的标配动态丨京东偷偷换了形象照,网友惊呼太可爱了有网友发现最近京东的LOGO又有变化了原先的小白狗Joy不仅改变了角度还变得圆润了不少果然岁月是把杀猪刀看来平日里也没少加班吃外卖吧当然这一回的视觉效果也更加立体有点从2D变3D的肩比罗德小蜜蜂,国产智麦产品更具性价比vlog已经成为一项全面娱乐项目,出门遛个弯你都可以随处可见大爷大妈在广场上不仅是在跳舞,还在做直播。而对于当下的年轻人来说,作为干饭人,直播拍日常vlog小段子亦或者类似我这样的为什么苹果的产品卖得贵,销量还特别好?你们好,这里是Seek思科,为你寻找苹果最新资讯苹果隐藏技巧苹果良心APP以及苹果优质配件。如果你需要这些,不妨点个关注。几乎每年新款iPhone发布后不久,就开始有机构拆解后发布面对疾风吧!飞宇KiCAJetFan涡轮扇每秒11。5米疾风来袭抵抗夏日夏天来了,又到了人手一个小风扇的季节,之所以手持小风扇这么火,就是因为它们足够便携而且内置电源,基本上都能提供两三个小时的续航,差不多够用,毕竟除了户外劳动者建筑工人旅游博主等,一vivoX70发布时间确定,处理器基本不变,影像实力有大提升vivo该公司可能会在国内近期宣布vivoX70系列。而近日外媒TipsterDigitalChatStation爆料了有关X70系列的屏幕和摄像头功能的一些细节参数。事实上,现在连汉服小姐姐都被圈粉?绿厂这款Reno6星黛紫究竟什么来路紫色一直都是时尚圈的宠儿,不同于蓝红黄这样明亮温暖的颜色,紫色一直都给一种神秘的高级感,这也是其一直处于不败之地的重要原因。时尚圈很容易见到的紫色,在手机圈却并不常见,因为一旦弄不2999元有戏!红米K50Pro规格被曝光,双环摄像头很惹眼现在的红米掌握着中国中低端机领域话语权的同时,在冲击高端这件事上也表现出满满的信心,可以说是众多友商无法去忽视对手了。是的,最近的K40系列表现很出色,不过如今的新旧旗舰交替速度非英国拆除华为设备,最大芯片厂却被中企收购,欠债已超5000万众所周知英国在对华为的态度上可以说是非常坚定,紧紧跟随美国的步伐,清除华为设备,但没想到其境内最大的芯片厂,如今却被中企收购,正所谓是捡了芝麻,丢了西瓜。英国向美国看齐虽然我国在通1亿像素副屏设计,一加9T系列曝光,8月份前后发布?高通6月底发布骁龙888Plus芯片,意味着下半年新机潮即将到来,各大厂商摩拳擦掌蓄势待发。近日有海外博主爆料,一加9T预计将于今年第三季度发布,相比往年会提前一段时间,大概率会在