Java Reference
In-Depth Information
A better solution would be to have each thread get notified only when the record it is
interested in becomes free.
Under JDK 1.4 this would have been difficult to achieve; you would have had to synchro-
nize on different objects to be able to ensure that only a specific thread gets notified. Under
JDK 5 you can have all your threads obtain a lock on the same object but use different
Condition s upon which they should be notified.
JDK 1.5's reentrant locks, with their different syntax to synchronized blocks, provide the
ability to create hand-over-hand locking, where a lock is requested, then a second lock is
requested, then the first lock is released, and so on. No lock in the chain is released until the
next lock is granted.
Conceptually the replacement for the reserveDVD method would look like the code in List-
ing 5-3. Note that the line numbers are specific to this discussion, and have no relationship to
the line numbers for the original reserveDvd method.
Listing 5-3. A Less CPU-Intensive reserveDvd Method
1 private static Map<String, LockInformation> reservations
2 = new HashMap<String, LockInformation>();
3
4 private static Lock masterLock = new ReentrantLock();
5
6 public boolean reserveDvd(String upc, DvdDatabase renter)
7 throws InterruptedException {
8 LockInformation dvdLock = null;
9 masterLock.lock();
10 try {
11 dvdLock = reservations.get(upc);
12 if (dvdLock == null) {
13 dvdLock = new LockInformation();
14 reservations.put(upc, dvdLock);
15 }
16 dvdLock.lock();
17 } finally {
18 masterLock.unlock();
19 }
20
21 try {
22 long endTimeMSec = System.currentTimeMillis() + 5000;
23 Condition dvdCondition = dvdLock.getCondition();
24 while (dvdLock.isReserved()) {
25 long timeLeftMSec = endTimeMSec - System.currentTimeMillis();
26 if (!dvdCondition.await(timeLeftMSec, TimeUnit.MILLISECONDS)) {
27 return false;
28 }
29 }
30 dvdLock.setReserver(renter);
31 } finally {
Search WWH ::




Custom Search