- 浏览: 483704 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
龘龘龘:
TrueBrian 写道有个问题,Sample 1中,为了控制 ...
What's New on Java 7 Phaser -
龘龘龘:
楼主总结的不错。
What's New on Java 7 Phaser -
TrueBrian:
有个问题,Sample 1中,为了控制线程的启动时机,博主实际 ...
What's New on Java 7 Phaser -
liguanqun811:
不知道楼主是否对zookeeper实现的分布式锁进行过性能测试 ...
Distributed Lock -
hobitton:
mysql的get lock有版本限制,否则get lock可 ...
Distributed Lock
Inside AbstractQueuedSynchronizer (4)
- 博客分类:
- SE
- Concurrent
Inside AbstractQueuedSynchronizer (1)
Inside AbstractQueuedSynchronizer (2)
Inside AbstractQueuedSynchronizer (3)
Inside AbstractQueuedSynchronizer (4)
3.6 ConditionObject
AbstractQueuedSynchronizer的内部类ConditionObject实现了Condition接口。Condition接口提供了跟Java语言内置的monitor机制类似的接口:await()/signal()/signalAll(),以及一些支持超时和回退的await版本。可以将任意个数的ConcitionObject关联到对应的synchronizer,例如通过调用ReentrantLock.newCondition()方法即可构造一个ConditionObject实例。每个ConditionObject实例内部都维护一个ConditionQueue,该队列的元素跟AbstractQueuedSynchronizer的WaitQueue一样,都是Node对象。
ConditionObject的await()代码如下:
public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); int interruptMode = 0; while (!isOnSyncQueue(node)) { LockSupport.park(this); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) // clean up if cancelled unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); }
以上代码中,可以看出ConditionObject的await语义跟Java语言内置的monitor机制是非常相似的(详见:http://whitesock.iteye.com/blog/162344 )。首先addConditionWaiter()将当前线程加入到ConditionQueue中,然后fullyRelease(node)释放掉跟ConditionObject关联的synchronizer锁。如果某个线程在没有持有对应的synchronizer锁的情况下调用某个ConditionObject对象的await()方法,那么跟Object.wait()一样会抛出IllegalMonitorStateException。接下来while (!isOnSyncQueue(node)) {...}会保证在其它线程调用了该ConditionObject的signal()/siangalAll()之前,当前线程一直被阻塞(signal()/siangalAll()的行为稍后会介绍)。在被signal()/siangalAll()唤醒之后,await()通过acquireQueued(node, savedState)确保再次获得synchronizer的锁。
ConditionObject的signal()代码如下:
public final void signal() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignal(first); } private void doSignal(Node first) { do { if ( (firstWaiter = first.nextWaiter) == null) lastWaiter = null; first.nextWaiter = null; } while (!transferForSignal(first) && (first = firstWaiter) != null); }
那么跟await()一样,如果某个线程在没有持有对应的synchronizer锁的情况下调用某个ConditionObject对象的signal()/siangalAll()方法,会抛出IllegalMonitorStateException。signal()主要的行为就是将ConditionQueue中对应的Node实例transfer到AbstractQueuedSynchronizer的WaitQueue中,以便在synchronizer release的过程中,该Node对应的线程可能被唤醒。
3.7 Timeout & Cancellation
AbstractQueuedSynchronizer的acquireQueued()和doAcquire***()系列方法在acquire失败(超时或者中断)后,都会调用cancelAcquire(Node node)方法进行清理,其代码如下:
private void cancelAcquire(Node node) { // Ignore if node doesn't exist if (node == null) return; node.thread = null; // Skip cancelled predecessors Node pred = node.prev; while (pred.waitStatus > 0) node.prev = pred = pred.prev; // predNext is the apparent node to unsplice. CASes below will // fail if not, in which case, we lost race vs another cancel // or signal, so no further action is necessary. Node predNext = pred.next; // Can use unconditional write instead of CAS here. // After this atomic step, other Nodes can skip past us. // Before, we are free of interference from other threads. node.waitStatus = Node.CANCELLED; // If we are the tail, remove ourselves. if (node == tail && compareAndSetTail(node, pred)) { compareAndSetNext(pred, predNext, null); } else { // If successor needs signal, try to set pred's next-link // so it will get one. Otherwise wake it up to propagate. int ws; if (pred != head && ((ws = pred.waitStatus) == Node.SIGNAL || (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) && pred.thread != null) { Node next = node.next; if (next != null && next.waitStatus <= 0) compareAndSetNext(pred, predNext, next); } else { unparkSuccessor(node); } node.next = node; // help GC } }
需要注意的是, cancelAcquire(Node node)方法是可能会被并发调用。while (pred.waitStatus > 0) {...}这段循环的作用就是清除当前Node之前的已经被标记为取消的节点,但是head节点除外(因为head节点保证不会被标记为Node.CANCELLED)。这段循环初看起来有并发问题,但是推敲一下之后发现:循环过程中函数参数node的waitStatus不会大于0,因此即使是多个线程并发执行这个循环,那么这些线程处理的都只是链表中互不重叠的一部分。接下来在node.waitStatus = Node.CANCELLED执行完毕之后,后续的操作都必须要避免并发问题。
关于处理线程中断, ConditionObject的await()/signal()/signalAll()等方法符合JSR 133: Java Memory Model and Thread Specification Revision中规定的语义:如果中断在signal之前发生,那么await必须在重新获得synchronizer的锁之后,抛出InterruptedException;如果中断发生在signal之后发生,那么await必须要设定当前线程的中断状态,并且不能抛出InterruptedException。
4 Reference
The java.util.concurrent Synchronizer Framework
The Art of Multiprocessor Programming
发表评论
-
Understanding the Hash Array Mapped Trie
2012-03-30 10:36 0mark -
Atomic Bit Operation in Linux Kernel
2012-02-08 00:27 2100Linux Kernel支持atomic bit operat ... -
A Hierarchical CLH Queue Lock
2012-01-14 19:01 2150A Hierarchical CLH Queue Lock ( ... -
Inside AbstractQueuedSynchronizer (3)
2012-01-07 23:37 4729Inside AbstractQueuedSynchroniz ... -
Inside AbstractQueuedSynchronizer (2)
2012-01-07 17:54 6367Inside AbstractQueuedSynchroniz ... -
Inside AbstractQueuedSynchronizer (1)
2012-01-06 11:04 7948Inside AbstractQueuedSynchroniz ... -
Code Optimization
2011-10-14 00:11 1608当前开发人员在进行编码的时候,可能很少关注纯粹代码级别的优化了 ... -
Distributed Lock
2011-08-02 22:02 92111 Overview 在分布式系统中,通常会 ... -
What's New on Java 7 Phaser
2011-07-29 10:15 82721 Overview Java 7的并 ... -
Sequantial Lock in Java
2011-06-07 17:00 22141 Overview Linux内核中常见的同步机 ... -
Feature or issue?
2011-04-26 22:23 121以下代码中,为何CglibTest.intercept ... -
Bloom Filter
2010-10-19 00:41 50731 Overview Bloom filt ... -
Inside java.lang.Enum
2010-08-04 15:40 64761 Introduction to enum J ... -
Open Addressing
2010-07-07 17:59 34581 Overview Open addressi ... -
JLine
2010-06-17 09:11 11008Overview JLine 是一个用来处理控 ... -
ID Generator
2010-06-14 14:45 1676关于ID Generator,想 ... -
inotify-java
2009-07-22 22:58 82971 Overview 最近公 ... -
Perf4J
2009-06-11 23:13 84871 Overview Perf4j是一个用于计算 ... -
Progress Estimator
2009-02-22 19:37 1534Jakarta Commons Cookbook这本书 ... -
jManage
2008-12-22 00:40 39571 Overview 由于项目需要, 笔者开发了一个 ...
相关推荐
4. 注意平台兼容性问题,确保生成的C#代码能在目标平台上正常工作。 总的来说,"CLRInsideOut"是一个非常实用的工具,它为.NET开发者提供了便利,使得他们可以更轻松地与C/C++世界进行交互,从而扩展.NET应用程序的...
Allegro自带的ODB++inside工具下载,ODB++inside插件可以将Allegro的.brd文件转化为仿真工具Hyperlynx使用的文件。共6个文件,需要分别下载。 ODB_Inside_Cadence_Allegro_111_Windows_64_SA_Setup.zip.001 ODB_...
Allegro自带的ODB++inside工具下载,ODB++inside插件可以将Allegro的.brd文件转化为仿真工具Hyperlynx使用的文件。共6个文件,需要分别下载。 ODB_Inside_Cadence_Allegro_111_Windows_64_SA_Setup.zip.001 ODB_...
Allegro自带的ODB++inside工具下载,ODB++inside插件可以将Allegro的.brd文件转化为仿真工具Hyperlynx使用的文件。共6个文件,需要分别下载。 ODB_Inside_Cadence_Allegro_111_Windows_64_SA_Setup.zip.001 ODB_...
Allegro自带的ODB++inside工具下载,ODB++inside插件可以将Allegro的.brd文件转化为仿真工具Hyperlynx使用的文件。共6个文件,需要分别下载。 ODB_Inside_Cadence_Allegro_111_Windows_64_SA_Setup.zip.001 ODB_...
4. **继承与多态**:C++的继承是实现面向对象编程的关键特性。书中详述了继承层次结构中对象的构造与析构过程,以及虚函数和纯虚函数的使用,解释了多态的实现机制。 5. **模板元编程**:模板是C++中的泛型编程工具...
Allegro自带的ODB++inside工具下载,DBinside插件可以将Allegro的.brd文件转化为仿真工具Hyperlynx使用的文件。共6个文件,需要分别下载。 ODB_Inside_Cadence_Allegro_111_Windows_64_SA_Setup.zip.001 ODB_Inside_...
4. **Struct Marshaling**:对于包含非托管数据类型的结构体,需要指定如何正确地布局和传递数据。 5. **Handle and Pointer Marshaling**:处理非托管的句柄(如HINSTANCE、HWND等)和指针,确保安全的内存访问。 ...
Microsoft Excel 2010 Inside Out 英文无水印原版pdf pdf所有页面使用FoxitReader、PDF-XChangeViewer、SumatraPDF和Firefox测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细...
4. **强大的电气规则检查**:ODB++支持电气规则检查,可以在早期阶段发现和修复设计问题。 5. **自动化制造文件生成**:使用ODB++,可以自动生成制造所需的各种文件,如Gerber、NC钻孔文件等,降低了人工介入的风险...
文档标题为《Inside游戏效果文档》,描述了PlayDead公司在制作游戏《Inside》时所采用的渲染技术。文档内容涉及了游戏中的雾效、HDR泛光(bloom)以及其他与光照和渲染相关的高级技术。这些技术对于创造游戏的独特...
《Inside SQLite》这本书深入探讨了其内部工作原理和技术细节。 首先,我们来看看“深入sqlite.docx”。这可能是作者个人对SQLite的深入理解和研究,可能包含了SQLite的架构解析、存储机制、查询优化、事务处理、...
《Inside NAND Flash Memories》这本书由Rino Micheloni、Luca Crippa和Alessia Marelli共同编写,并由Springer出版社出版。本书详细介绍了NAND闪存的工作原理和技术细节,对于理解NAND闪存在现代数字系统中的作用...
inside ole 英文版,还是英文版看着舒服!inside ole 英文版,还是英文版看着舒服!inside ole 英文版,还是英文版看着舒服!inside ole 英文版,还是英文版看着舒服!inside ole 英文版,还是英文版看着舒服!...
4. 互操作性:被多个EDA厂商和制造系统支持,促进了跨平台合作。 总的来说,"ODB++ Inside Cadence Allegro"结合了Allegro的强大设计功能和ODB++的高效数据交换能力,为电子设计工程师提供了流畅的工作流程,特别是...
Microsoft Excel 2013 Inside Out
Inside JVM
ODB++ Inside Cadence Allegro 11.4 Windows 64 SA Setup是一个专门针对Cadence Allegro设计平台的官方插件,主要用于支持ODB++数据格式的输入和输出。ODB++是一种广泛使用的电子设计自动化(EDA)数据交换标准,它...
1. I-BUS Inside 标题“Inside the BMW Cars entertainement Serial Bu”可能是指I-BUS系统的内部结构和工作原理。I-BUS(Inter Equipment Bus)是一种用于汽车内部通信的总线系统,用于连接汽车内的多个电子控制...
《 Typora inside主题详解与应用指南》 在数字化文档编辑的世界里,Typora以其简洁、优雅的界面设计和强大的Markdown支持,受到了众多用户的喜爱。而Typora-inside-theme-master.zip这个压缩包则为Typora用户带来了...