java.util.concurrent.atomic facilitates the use of variables in a concurrent environment.
It provides a means of efficiently updating the value of a variable without the use of locks.
This is accomplished through the use of classes, such as AtomicInteger and AtomicLong,
and methods, such as compareAndSet( ), decrementAndGet( ), and getAndSet( ). These
methods execute as a single, non-interruptible operation.
java.util.concurrent.locks provides an alternative to the use of synchronized methods. At
the core of this alternative is the Lock interface, which defines the basic mechanism used to
acquire and relinquish access to an object. The key methods are lock( ), tryLock( ), and unlock( ).
The advantage to using these methods is greater control over synchronization.
The remainder of this chapter takes a closer look at the constituents of the concurrent API.
Using Synchronization Objects
It is likely that the most widely used part of the concurrent API will be its synchronization
objects. These are supported by the Semaphore, CountDownLatch, CyclicBarrier, and
Exchanger classes. Collectively, they enable you to handle several formerly difficult
synchronization situations with ease. They are also applicable to a wide range of programs--
even those that contain only limited concurrency. Because the synchronization objects will
be of interest to nearly all Java programs, each is examined here in some detail.
The synchronization object that many readers will immediately recognize is Semaphore,
which implements a classic semaphore. A semaphore controls access to a shared resource
through the use of a counter. If the counter is greater than zero, then access is allowed. If it
is zero, then access is denied. What the counter is counting are permits that allow access to
the shared resource. Thus, to access the resource, a thread must be granted a permit from the
In general, to use a semaphore, the thread that wants access to the shared resource tries
to acquire a permit. If the semaphore's count is greater than zero, then the thread acquires a
permit, which causes the semaphore's count to be decremented. Otherwise, the thread will
be blocked until a permit can be acquired. When the thread no longer needs access to the
shared resource, it releases the permit, which causes the semaphore's count to be incremented.
If there is another thread waiting for a permit, then that thread will acquire a permit at that
time. Java's Semaphore class implements this mechanism.
Semaphore has the two constructors shown here:
Semaphore(int num, boolean how)
Here, num specifies the initial permit count. Thus, num specifies the number of threads that
can access a shared resource at any one time. If num is one, then only one thread can access
Search WWH :