Java Reference
In-Depth Information
Note Notice that even though displayOrders doesn't use the inventoryMap ,
you still synchronize on it (in solution 1). Because the inventoryMap is the main
collection, even operations done on secondary collections will still need to be protected
by the main collection synchronization.
Solution 2 is more explicit, offering an independent lock that is used to coordinate
the atomic operations instead of picking a principal collection. Locking refers to the
ability of the JVM to restrict certain code paths to be executed by only one thread.
Threads try to obtain the lock (locks are provided, for example, by a
ReentrantLock instance, as shown in the example), and the lock can be given to
only one thread at a time. If other threads were trying to acquire the same lock, they
will be suspended ( WAIT ) until the lock becomes available. The lock becomes avail-
able when the thread that currently holds the lock releases it. When a lock is released, it
can then be acquired by one (and only one) of the threads that were waiting for that
lock.
Locks by default are not “fair.” In other words, the order of the threads that reques-
ted the lock is not kept; this allows for very fast locking/unlocking implementation in
the JVM, and in most situations, it is generally okay to use unfair locks. On a very
highly contended lock, if there is a requirement to evenly distribute the lock (make it
fair), you do so by setting the setFair property on the lock.
In solution 2, calling the inventoryLock.lock() method, will either acquire
the lock and continue, or will suspend execution ( WAIT ) until the lock can be acquired.
Once the lock is acquired, no other thread will be able to execute within the locked
block. At the end of the block, the lock is released by calling invent-
oryLock.unlock() .
It is common practice when working with Lock objects ( ReentrantLock ,
ReadLock , and WriteLock ) to surround the use of these Lock objects by a try/
finally clause. After opening the try block, the first instruction would be a call to
the lock.lock() method. This guarantees that the first instruction executed is the
acquisition of the lock. The release of the lock (by calling lock.unlock() ) is done
in the matching finally block. In the event of a RuntimeException occurring
while you have acquired the lock, unlocking within the finally clause assures that
one doesn't “keep” the lock and prevent other threads from acquiring it.
The use of the ReentrantLock object offers additional features that the syn-
chronized statement doesn't offer. As an example, the ReentrantLock has the
tryLock() function, which attempts to get the lock only if no other threads have it
Search WWH ::




Custom Search