这章来自3.1《Synchronization State》和3.2的《Blocking》。
AbstractQueuedSynchronizer会维护一个Int类型的synchronization state。公开了3个访问和更新state的方法,分别是:getState,setState和compareAndSetState。这些方法依赖java.util.concurrent.atomic和volatile。其中compare-AndSetState实现是依赖于CAS(compare-and-swap)或LL/SC(loadlinked/store-conditional)。CAS大家可能比较熟悉,(current ==expect)则设值。LL/SC则比CAS更严格,(current==expect && current 没有被restore)才算竞争成功。current被restore仍然等于current,CAS是竞争成功的。这是ABA问题。是否觉得LL/SC有点AtomicStampedReference的味道?的确,AtomicStampedReference是通过引进版本号来检测是否被restore。
用一个32位的int来表示synchronization state是一个实用的决定,虽然jsr166提供了64位的long的原子操作,但在一些平台上需要实用内部锁来实现,对性能有所影响。在未来可能引入一个用long来表示synchronization state的基类,但在现在还没有一个足够的理由把这个类包含进来。而且32位的state也满足了大部分应用的需要。只有一个synchronizer CyclicBarrier看起来需要更多的位来表示state。
继承于AbstractQueuedSynchronizer的具体类必须明确的定义tryAcquiretryRelease方法,用来控制acquire和release操作。如果synchronization 被获取,tryAcquire必须返回true。如果新的synchronization state允许以后的acquire,tryRelease也必须返回true。这些方法提供一个int的参数来表示希望的state。例如在一个可重入锁里,就需要计数,但对于大多数的synchronizer是可以忽略这个参数的。
在jsr166前,如果不基于嵌入的monitor,是没有可用的java api去block和unblock一个线程的。唯一的候选方法是Thread.spspend和Thread.resume。但是它们不符合要求,原因是:如果一个unblocking的线程在调用suspend被阻塞前调用了resume是没有效果的(这里是希望,如果在调用suspend前resume先被调用,suspend不会导致线程挂起)。
在并发包里包含了一个LockSupport的类,该类解决了这个问题。方法LockSupport.park会block当前线程,除非或直到LockSupport.unpark被调用。unpark的调用是不会被计数的,所以多次unpark只会影响之后的第一次park。然后这些应用是针对每个thread的,而不是每个synchronizer。一个thread在一个新的synchronizer调用了park可能马上返回,因为unpark在之前被调用了。如果没有unpark,那么下次调用park就会导致thread阻塞。可能会需要一个操作去清理thread 的state,使park可以阻塞thread,但是其实不需要这么做,在需要的情况下,多调用几次park更高效。
在某些程度上,这个简单的原理看上去和某些平台的某些机制很相像,例如在Solaris-9的thread library,windows的“consumeable events”,Linux NPTL thread library。park和unpark可以高效的映射到这些常见的支持jvm的平台上。park也支持相对和绝对的超时时间,并且可以和Thead.interrupt结合,interrupt一个thread可以unpark它。
分享到:
相关推荐
### Java.util.concurrent同步器框架详解 #### 概述 Java平台在J2SE 1.5版本中引入了`java.util.concurrent`包,这是一系列中等层次的并发支持类集合,通过Java社区过程(Java Community Process, JCP)的Java规范...
AQS(AbstractQueuedSynchronizer)是Java.util.concurrent包中同步器的基础框架,它的核心设计思想与实现方法在Doug Lea先生的这篇论文中有详细的介绍。论文详细阐述了AQS框架的原理、设计、实现、应用以及性能等...
文档标题“java.util.concurrent同步器框架”和描述“Doug Lea的java.util.concurrent同步器框架”表明本文将探讨由Doug Lea所撰写的关于Java并发编程中同步器框架的内容。文档中提到了AbstractQueuedSynchronizer类...
2. 并发处理:并发性是现代高负载服务的关键特性。此框架可能包含多线程或多进程支持,使得多个请求可以同时处理,提高系统吞吐量。并发处理能够更有效地利用硬件资源,提升整体性能。 3. PHP与C的结合:将PHP的...
这个工程是为了学习guava concurrent中的AbstractFuture而建立的,里面有可以运行的例子,再配合我的博客:https://blog.csdn.net/o1101574955/article/details/82889851,可以看明白guava concurrent的基本设计思路...
CoDeK-Java并发开发frameworK是一个非常简单的开源学术Java库,旨在帮助开发Java多线程并发应用程序。
concurrent-1.3.4.jar
backport-util-concurrent.jarbackport-util-concurrent.jarbackport-util-concurrent.jar
标题 "JDK concurrent" 指的是Java开发工具包(JDK)中的并发编程相关知识。并发编程是在多线程环境中同时执行多个任务的技术,它在现代计算机系统中至关重要,尤其是在多核处理器和高并发应用中。Java JDK提供了一...
Chapter 2. Concurrency on the JVM and the Java Memory Model Chapter 3. Traditional Building Blocks of Concurrency Chapter 4. Asynchronous Programming with Futures and Promises Chapter 5. Data-Parallel...
2. **Phaser** - 在3.1版本中,backport-util-concurrent引入了Phaser,这是一个可重用的同步帮助器类,支持多个参与者之间的有界同步,类似于CyclicBarrier和CountDownLatch,但更灵活。Phaser可以自动调整参与者...
concurrent-1.3.2.jar concurrent-1.3.2.jar
Concurrent.Thread.js 一个用来让javascript也进行多线程开发的包,感兴趣的快来下吧。
2. **同步通道算法**:同步通道包含两个队列,用于生产者(任务提交)和消费者(任务执行)的分离。当没有空闲线程时,新任务会被放入队列,然后线程池会尝试唤醒等待的空闲线程。 3. **有限链接队列算法**:与同步...
Windows并发编程指南 Concurrent Programming on Windows (english)part2Joe Duffy是Microsoft公司.NET框架团队中并行扩展功能的技术主管、架构师以及奠基者,就职于Visual Studio部门。除了编写代码和管理开发团队...
《并发编程:JavaScript中的Concurrent.Thread.js》 在IT领域,多线程编程是一种常见的优化技术,用于提高程序的执行效率。特别是在JavaScript这样的单线程环境中,由于其异步执行模型,多线程处理显得尤为重要。...
concurrent.jar web开发工具包
Simplx is a C++ development framework for building reliable cache-friendly distributed and concurrent multicore software. Simplx was developped by Tredzone SAS. We provide software technology ...