接上篇JDK中线程中实现同步等待闭环的一种方式 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com),为什么使用了FutureTask中的get方法就可以实现线程的同步等待?这就将重点讲述下FutureTask这个类了,实际上Future接口和实现Future接口的FutureTask类,代表异步计算的结果。其UML类继承图,如下:

    

  从上图看FutureTask除了实现Future接口外,还实现了Runnable接口。因此,FutureTask可以交给Executor执行,也可以由调用线程直接执行(FutureTask.run())。根据FutureTask.run()方法被执行的时机,FutureTask可以处于下面3种状态(线程状态转换参考线程基本方法及其对线程状态的影响 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)):

    1)未启动。FutureTask.run()方法还没有被执行之前,FutureTask处于未启动状态。当创建一个FutureTask,且没有执行FutureTask.run()方法之前,这个FutureTask处于未启动状态。

    2)已启动。FutureTask.run()方法被执行的过程中,FutureTask处于已启动状态。

    3)已完成。FutureTask.run()方法执行完后正常结束,或被取消(FutureTask.cancel(…)),或执行FutureTask.run()方法时抛出异常而异常结束,FutureTask处于已完成状。

    

    

  当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞;当FutureTask处于已完成状态时,执行FutureTask.get()方法将导致调用线程立即返回结果或抛出异常——非常类似于闭锁的语义。

  看看get()方法的实现:

    

  通过源码可以看到:get()方法使用AQS类型的同步状态来持有任务的状态——运行、完成或者取消(state变量),同时利用state变量也维护了一些额外的状态变量来持有计算的结果或者抛出异常。与利用AQS类实现同步器的类是不是似曾相识(#^.^#),所以FutureTask虽然代表异步执行的结果,但是可以通过get方法阻塞当前正在运行的线程实现同步等待异步结果。

  其还维护一个WaitNode q 指向正在运行计算任务的线程(当前正处于运行状态),这样任务被取消就可以终端该线程:

  get()方法的执行示意图如下图上半部分:

      

   

  



    

  

FutureTask类的get方法如何实现线程同步等待的更多相关文章

  1. java多线程系类:基础篇:05线程的等待与唤醒

    概要 本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. wait()和notify()3. wait(long t ...

  2. Java中Thread类的join方法到底是如何实现等待

    现在的场景是A线程执行:public void run(){ bThread.join(0);//把b线程加入到当前线程(a线程),等待b结束,当前a线程才会结束.}B线程执行public void ...

  3. JAVA中线程同步的方法(7种)汇总

    同步的方法: 一.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就 ...

  4. Java中线程同步的方法

    同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注 ...

  5. python语言中threading.Thread类的使用方法

    1. 编程语言里面的任务和线程是很重要的一个功能.在python里面,线程的创建有两种方式,其一使用Thread类创建 # 导入Python标准库中的Thread模块 from threading i ...

  6. java中线程同步的几种方法

    1.使用synchronized关键字 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注: synchro ...

  7. C#多线程---Event类实现线程同步

    一.简介 我们使用类(.net Framework中的类,如 AutoResetEvent, Semaphore类等)的方法来实现线程同步的时候,其实内部是调用操作系统的内核对象来实现的线程同步. S ...

  8. Java-多线程第三篇3种创建的线程方式、线程的生命周期、线程控制、线程同步、线程通信

    1.Java使用Thread类代表线程.     所有的线程对象必须是Thread类或其子类的实例. 当线程继承Thread类时,直接使用this即可获取当前线程,Thread对象的getName() ...

  9. JDK中线程中实现同步等待闭环的一种方式

    实际Thread类自带的join方法就实现了线程同步等待,具体可以通过案例实践,如下: 本文的重点不是join,而是另一种设计的同步等待实现,涉及的关键类有:Thread.Runable.Callab ...

随机推荐

  1. 梯度下降法实现(Python语言描述)

    原文地址:传送门 import numpy as np import matplotlib.pyplot as plt %matplotlib inline plt.style.use(['ggplo ...

  2. FastDFSJava客户端使用

    1.1.java客户端 余庆先生提供了一个Java客户端,但是作为一个C程序员,写的java代码可想而知.而且已经很久不维护了. 这里推荐一个开源的FastDFS客户端,支持最新的SpringBoot ...

  3. 《剑指offer》面试题53 - II. 0~n-1中缺失的数字

    问题描述 一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内.在范围0-n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字. 示例 1: 输入: [ ...

  4. 【刷题-LeetCode】123 Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

  5. 【刷题-PAT】A1135 Is It A Red-Black Tree (30 分)

    1135 Is It A Red-Black Tree (30 分) There is a kind of balanced binary search tree named red-black tr ...

  6. 百度云管家使用socks代理无法上传下载解决办法

    像前几篇随笔描述的那样,笔者在学校里通过shadowsocks使用ipv6访问双栈vps来免费使用外网,但是在设置百度云管家的代理时发现:使用socks代理客户端可以访问文件列表,但是无法上传下载. ...

  7. Servlet-概念及实现一个Servlet程序

    Servlet技术 一,Servlet概念 1,Servlet是JavaEE规范之一.规范就是接口 2,Servlet就是JavaWeb三大组件之一.三大组件分别是:Servlet程序.Filter过 ...

  8. String类-intern方法

    1 package cn.itcast.p1.string.demo; 2 3 class StringObjectDemo { 4 public static void main(String[] ...

  9. zabbix安装 报错 socket '/var/lib/mysql/mysql.sock' (13)]

    安装界面提示: Error connecting to database: Can't connect to local MySQL server through socket '/var/lib/m ...

  10. 不难懂-----type=number 去掉加减按钮并禁止鼠标滚轮滚动

    <style> /* 去除webkit中input的type="number"时出现的上下图标 */ input::-webkit-outer-spin-button, ...