while (synchronization state does not allow acquire) { enqueue current thread if not already queued; possibly block current thread;

}

dequeue current thread if it was queued;

And a release operation is:

update synchronization state;

if (state may permit a blocked thread to acquire) unblock one or more queued threads;

Support for these operations requires the coordination of three basic components:

•Atomically managing synchronization state

•Blocking and unblocking threads

•Maintaining queues

It might be possible to create a framework that allows each of these three pieces to vary independently。 However, this would neither be very efficient nor usable。 For example, the information kept in queue nodes must mesh with that needed for unblocking, and the signatures of exported methods depend on the nature of synchronization state。

The central design  decision  in the synchronizer  framework was to choose a concrete implementation of each of these three components, while still permitting a wide range  of  options in how they are used。 This intentionally limits the range of applicability, but provides efficient enough support that there is practically never a reason not to use the framework (and instead build synchronizers from scratch) in those cases where it does apply。

3。1Synchronization State

Class AbstractQueuedSynchronizer maintains synchro- nization state using only a single (32bit) int, and exports getState, setState, and compareAndSetState operations to access and update this state。 These methods in turn rely on java。util。concurrent。atomic support providing JSR133 (Java Memory Model) compliant volatile semantics on reads and writes, and access to native compare-and-swap or load- linked/store-conditional instructions to implement compare- AndSetState, that atomically sets state to a given new value only if it holds a given expected value。

Restricting synchronization state to a 32bit int was a pragmatic decision。 While JSR166 also provides atomic operations on 64bit long fields, these must still be emulated using internal locks on enough platforms that the resulting synchronizers would not perform well。 In the future, it seems likely that a second base class, specialized for use with 64bit state (i。e。, with long control arguments), will be added。 However, there is not now a compelling reason to include it in the package。 Currently, 32 bits suffice for most applications。 Only one java。util。concurrent synchronizer class, CyclicBarrier, would require  more bits to maintain state, so instead uses locks (as do most higher-level utilities in the package)。

Concrete classes based on AbstractQueuedSynchronizer must define methods tryAcquire and tryRelease in terms of these exported state methods in order to control  the  acquire and release operations。 The tryAcquire method must return true if synchronization was acquired, and the tryRelease method must return true if the new synchronization state may allow future acquires。 These methods accept a single int argument that can be used to communicate desired state; for example in a reentrant lock, to re-establish the recursion count when re-acquiring the lock after returning from a condition wait。 Many synchronizers do not need such an argument, and so just ignore it。

3。2Blocking

Until JSR166, there was no Java API available to block and unblock threads for purposes of creating synchronizers that  are not based on built-in monitors。 The only candidates were Thread。suspend and Thread。resume, which  are unusable because they encounter an unsolvable  race problem: If an unblocking thread invokes resume before  the blocking thread has executed suspend, the resume operation will have no effect。

The java。util。concurrent。locks package includes a LockSup- port class with methods that address this problem。 Method LockSupport。park blocks the current thread unless or  until a LockSupport。unpark has been issued。 (Spurious wakeups are also permitted。) Calls to unpark are not "counted", so multiple unparks before a park only unblock a single park。 Additionally, this applies per-thread, not per-synchronizer。 A thread invoking park on a new synchronizer might return immediately because of a "leftover" unpark from a previous usage。 However, in the absence of an unpark, its  next invocation will block。 While it would be possible to explicitly clear this state, it is not worth doing so。 It is more efficient to invoke park multiple times when it happens to be necessary。

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

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

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

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

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

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

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

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

网络语言“XX体”研究

张洁小说《无字》中的女性意识

麦秸秆还田和沼液灌溉对...

LiMn1-xFexPO4正极材料合成及充放电性能研究

我国风险投资的发展现状问题及对策分析

老年2型糖尿病患者运动疗...

新課改下小學语文洧效阅...

ASP.net+sqlserver企业设备管理系统设计与开发

互联网教育”变革路径研究进展【7972字】

安康汉江网讯