The basic await operation is:

create and add new node to condition queue; release  lock;

block until node is on lock queue; re-acquire lock;

And the signal operation is:

transfer the first node from condition queue to lock queue;

Because these operations are performed only when the lock is held, they can use sequential linked queue operations (using a nextWaiter field in nodes) to maintain the condition queue。 The transfer operation simply unlinks the first node from the condition queue, and then uses CLH insertion to attach it to the lock queue。

}

And the release operation is:

if (tryRelease(arg) && head node's signal bit is set) { compareAndSet head's signal bit to false;

unpark head's successor, if one exists

}

The number of iterations of the main acquire loop depends, of course, on the nature of tryAcquire。  Otherwise,  in the absence of cancellation, each component of acquire and release is a constant-time O(1) operation, amortized across threads, disregarding any OS thread scheduling occuring within  park。

Cancellation support mainly entails checking for interrupt or timeout upon each return from park inside the acquire loop。 A cancelled thread due to timeout or interrupt sets  its node status and unparks its successor so it may reset links。 With cancellation, determining predecessors and successors and resetting status may include O(n) traversals (where n is the length of the queue)。 Because a thread never again blocks for a cancelled operation, links and status fields tend to restabilize quickly。

3。4Condition Queues

The synchronizer framework provides a ConditionObject class for use by synchronizers that maintain exclusive synchronization and conform to the Lock interface。 Any number of condition objects may be attached to a lock object, providing classic monitor-style await, signal, and signalAll operations, including those with timeouts, along with some inspection and monitoring methods。

The main complication in implementing these operations is dealing with cancellation of condition waits due to timeouts or Thread。interrupt。 A cancellation and signal occuring at approximately the same time encounter a race whose outcome conforms to the specifications for built-in monitors。 As revised in JSR133, these require that if an interrupt occurs before a signal, then the await method must, after re-acquiring the lock, throw InterruptedException。 But if it is interrupted after a signal, then the method must return without throwing an exception, but with its thread interrupt status set。

To maintain proper ordering, a bit in the queue node  status records whether the node has been (or is in the process of being) transferred。  Both the signalling code and the cancelling code  try to compareAndSet this status。 If a signal operation loses this race, it instead transfers the next node on the queue, if one exists。 If a cancellation loses, it must abort the transfer, and then await lock re-acquisition。 This latter case introduces  a  potentially unbounded spin。 A cancelled wait cannot commence lock re- acquisition until the node has been successfully inserted on the lock queue, so must spin waiting for the CLH queue insertion compareAndSet being performed by the signalling thread to succeed。 The need to spin here is rare, and employs a Thread。yield to provide a scheduling hint that some other thread, ideally the one doing the signal, should instead run。 While it would be possible to implement here a helping strategy for the cancellation to insert the node, the case is much too rare to justify the added overhead that this would entail。 In all other cases, the basic mechanics here and elsewhere use no spins or yields, which maintains reasonable performance on uniprocessors。

4。USAGE

Class AbstractQueuedSynchronizer ties together the above functionality and serves as a "template method pattern" [6] base class for synchronizers。 Subclasses define only the methods that implement the state inspections and updates that control acquire and release。 However, subclasses of Ab- stractQueuedSynchronizer are not themselves usable as synchronizer ADTs, because the class necessarily exports the methods needed to internally control acquire and release policies, which should not be made visible to users of these classes。 All java。util。concurrent synchronizer classes declare a private inner AbstractQueuedSynchronizer subclass and delegate all synchronization methods to it。 This also allows public methods to be given names appropriate to the synchronizer。

上一篇:基于约束的纸箱折叠仿真英文文献和中文翻译
下一篇:概率风能模型的发电系统可靠性英文文献和中文翻译

永磁同步电动机的矢量控...

JSP应用框架英文文献中文翻译

SSH框架实现的试题库管理...

塑料注射成型工艺参数优...

冷弯钢门户框架的设计方...

耦合侧向扭转频率的不对...

斜屋顶钢框架结构的弹性...

上海居民的社会参与研究

压疮高危人群的标准化中...

STC89C52单片机NRF24L01的无线病房呼叫系统设计

基于Joomla平台的计算机学院网站设计与开发

提高教育质量,构建大學生...

浅谈高校行政管理人员的...

从政策角度谈黑龙江對俄...

AES算法GPU协处理下分组加...

酵母菌发酵生产天然香料...

浅论职工思想政治工作茬...