由FutureTask的get方法靠什么机制来阻塞引发的思考
1. FutureTask的get方法靠什么机制来阻塞
看其get方法源码:
/**
* @throws CancellationException {@inheritDoc}
*/
public V get() throws InterruptedException, ExecutionException {
return sync.innerGet();
}
不难发现,FutureTask是依靠其内部类java.util.concurrent.FutureTask.Sync<V>类来实现阻塞。
Sync又是实现了AbstractQueuedSynchronizer类。
private final class Sync extends AbstractQueuedSynchronizer
看都有谁实现了这个类:

里面有很多我们平时用到的,但是不怎么清楚其原理的类,原来都是靠实现AbstractQueuedSynchronizer来达到相应的同步机制。
AbstractQueuedSynchronizer又是靠什么来实现阻塞以及维持协调好各竞争线程间的资源分配的?看下一段。
2. 分析AbstractQueuedSynchronizer
从上面分析来看AbstractQueuedSynchronizer应该是JDK的concurrent包里比较重要的一个机制。用google先了解下他的面貌:

中文的blog的搜索结果说明有很多人对这个做了总结与学习,最下面框起来的一个pdf结果应该是对这个的一个论文。
论文中阐述了几点比较关键的地方
1. 方法命名的问题
“
同步器一般包含两种方法,一种是acquire,另一种是release。acquire操作阻塞调用的线程,直到或除非同步状态允许其继续执行。而release操作则是通过某种方式改变同步状态,使得一或多个被acquire阻塞的线程继续执行。
j.u.c包中并没有对同步器的API做一个统一的定义。因此,有一些类定义了通用的接口(如Lock),而另外一些则定义了其专有的版本。因此在不同的 类中,acquire和release操作的名字和形式会各有不同。例 如:Lock.lock,Semaphore.acquire,CountDownLatch.await和FutureTask.get,在这个框架 里,这些方法都是acquire操作。但是,J.U.C为支持一系列常见的使用选项,在类间都有个一致约定。在有意义的情况下,每一个同步器都支持下面的 操作:
阻塞和非阻塞(例如tryLock)同步。
可选的超时设置,让调用者可以放弃等待
通过中断实现的任务取消,通常是分为两个版本,一个acquire可取消,而另一个不可以。
”
2. 实现同步器的三个“组件”
“
为了实现上述操作,需要下面三个基本组件的相互协作:
a) 同步状态的原子性管理;
b) 线程的阻塞与解除阻塞;
c) 队列的管理;
”
怎么实现这三个部件,论文中有详细介绍。
论文中提到“整个框架的关键就是如何管理被阻塞的线程的队列”也就是对应上面三个“组件”的c部分。
AQS中使用了CLH队列。
为什么采用CLH而不是MCS,因为CLH更容易实现取消与超时机制。
3. CLH队列
谈CLH队列时,前面要先谈很多基础知识,不然直接阅读上面的简明介绍,会有点坡度。
4. AQS思维导图


5. FutureTask思维导图

由FutureTask的get方法靠什么机制来阻塞引发的思考的更多相关文章
- TableVie优化方法和优化机制
1,UITableview的优化方法(缓存高度,异步绘制,减少层级,hide,避免离屏渲染) (1)缓存高度:当我们创建frame模型的时候,计算出来cell的高度的时候,我们可以将cell的高度缓存 ...
- Scrapy(爬虫框架)中,Spider类中parse()方法的工作机制
parse(self,response):当请求url返回网页没有指定回调函数,默认的Request对象的回调函数,用来处理网页返回的response,和生成的Item或者Request对象 以下分析 ...
- 我的Java开发学习之旅------>Java语言中方法的参数传递机制
实参:如果声明方法时包含来了形参声明,则调用方法时必须给这些形参指定参数值,调用方法时传给形参的参数值也被称为实参. Java的实参值是如何传入方法?这是由Java方法的参数传递机制来控制的,Java ...
- 深入理解Java中方法的参数传递机制
形参和实参 我们知道,在Java中定义方法时,是可以定义参数的,比如: public static void main(String[] args){ } 这里的args就是一个字符串数组类型的参数. ...
- Java方法之参数传递机制
目录 Java方法之参数传递机制 基本数据类型 引用数据类型 综合练习 总结 Java方法之参数传递机制 Java方法中如果声明了形参,在调用方法时就必须给这些形参指定参数值,实际传进去的这个值就叫做 ...
- JavaSE 面试题: 方法的参数传递机制
JavaSE 面试题 方法的参数传递机制 import java.util.Arrays; public class Test { public static void main(String[] a ...
- Java高频经典面试题(第一季)四:方法的参数传递机制
考点? 方法的参数传递机制 String,包装类等对象的不可变性 方法的参数传递机制: ①形参是基本数据类型 传递数据值 ②实参是引用数据类型 传递地址值 特殊的类型:String.包装类等对象不可变 ...
- class_copyIvarList方法获取实例变量问题引发的思考
在runtime.h中,你可以通过其中的一个方法来获取实例变量,那就是class_copyIvarList方法,具体的实现如下: - (NSArray *)ivarArray:(Class)cls { ...
- java中方法的参数传递机制(值传递还是引用传递)
看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参 ...
随机推荐
- Codeforces Beta Round #35 (Div. 2) E. Parade(扫描线)
题目链接 只要会做,周长并,这题肯定有思路. 有个小地方敲错了,细心啊,扫描线,有一段时间没写过了,还有注意排序的问题,很重要. #include <iostream> #include ...
- 开篇&TexturePacker打出图集给UGUI使用
开篇: 前段时间,网上流出了一套手游源码,本想着把服务器端搭一下,给自己认识小伙伴们调试着把这套源码学习一下.于是就买一个阿里云服务器,可是花了几天时间,就是run不起来了啊.还好网上已经有人搭出来了 ...
- Linux之线程管理
linux下查看线程数的几种方法 1. cat /proc/${pid}/status [root@limt01 2325]# ps -ef|grep xinetd|grep -v grep ro ...
- wind.onload和$(document).ready()的区别例示
例子: <html> <script type="text/javascript" src="jquery-1.7.1.min.js"> ...
- RSA_RSA算法原理(一)
如果你问我,哪一种算法最重要?我可能会回答"公钥加密算法". 因为它是计算机通信安全的基石,保证了加密数据不会被破解.你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先简 ...
- asp.net发送邮件
using System.Net.Mail; /// 发送邮件 /// </summary> /// <param name="sender"></p ...
- [LintCode] Divide Two Integers 两数相除
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
- springMVC工作机制和框架搭建配置说明
先说一下springMVC的工作机制 1.springmvc把 所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作. 2.Dispatcher ...
- 开启ACM的征途
ACM对我的诱惑实在是太大了.以前从没有任何一件事情让我在假期也这么热血沸腾过,甚至是高考,也从没有过. 我对ACM的目标从没变过,我要拿金牌,我要进WF! 尽管我现在才刚刚开始ACM之旅,尽管我现在 ...
- VMwareTools安装笔记
1.首先确保你的虚拟机正在运行. 2.右键点击“安装VMwareTools”,如果安装过了,会显示“重新安装...” 3.系统会自动打开VMwareTools的目录,(一般都会自动打开,因为系统一般会 ...