深度解析Java8 – AbstractQueuedSynchronizer的实现分析(下)
前言
经过本系列的上半部分JDK1.8 AbstractQueuedSynchronizer的实现分析(上)的解读,相信很多读者已经对AbstractQueuedSynchronizer(下文简称AQS)的独占功能了然于胸,那么,这次我们再借助另一个工具类:CoutDownLatch,换个角度看看AQS的另外一个重要功能——共享功能的实现。
经过本系列的上半部分JDK1.8 AbstractQueuedSynchronizer的实现分析(上)的解读,相信很多读者已经对AbstractQueuedSynchronizer(下文简称AQS)的独占功能了然于胸,那么,这次我们再借助另一个工具类:CoutDownLatch,换个角度看看AQS的另外一个重要功能——共享功能的实现。
本文首发在infoQ :www.infoq.com/cn/articles/jdk1.8-abstractqueuedsynchronizer
Java中的FutureTask作为可异步执行任务并可获取执行结果而被大家所熟知,通常可以使用future.get()来获取线程的执行结果,在线程执行结束之前,get方法会一直阻塞状态,直到call()返回,其优点是使用线程异步执行任务的情况下还可以获取到线程的执行结果,但是FutureTask的以上功能却是依靠通过一个叫AbstractQueuedSynchronizer的类来实现,至少在JDK 1.5、JDK1.6版本是这样的(从1.7开始FutureTask已经被其作者Doug Lea修改为不再依赖AbstractQueuedSynchronizer实现了,这是JDK1.7的变化之一)。但是AbstractQueuedSynchronizer在JDK1.8中还有如下图所示的众多子类:
感谢同事【魏鹏】投递本稿。 Dedicate to Molly.
提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架。该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础。使用的方法是继承,子类通过继承同步器并需要实现它的方法来管理其状态,管理的方式就是通过类似acquire和release的方式来操纵状态。然而多线程环境中对状态的操纵必须确保原子性,因此子类对于状态的把握,需要使用这个同步器提供的以下三个方法对状态进行操作:
子类推荐被定义为自定义同步装置的内部类,同步器自身没有实现任何同步接口,它仅仅是定义了若干acquire之类的方法来供使用。该同步器即可以作为排他模式也可以作为共享模式,当它被定义为一个排他模式时,其他线程对其的获取就被阻止,而共享模式对于多个线程获取都可以成功。
声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González 译者:许巧辉
实现一个自定义的Lock类
锁是Java并发API提供的基本同步机制之一。它允许程序员保护代码的临界区,所以,在某个时刻只有一个线程能执行这个代码块。它提供以下两种操作:
在Java并发API中,锁是在Lock接口及其一些实现类中声明的,比如ReentrantLock类。
在这个指南中,你将学习如何实现你自己的Lock对象,它将实现一个实现了Lock接口并可用来保护临界区的类。