Java Reference
In-Depth Information
Why wouldn't this work? After all, putIfAbsent is synchronized , right? The problem
is that it synchronizes on the wrong lock . Whatever lock the List uses to guard its state,
it sure isn't the lock on the ListHelper . ListHelper provides only the illusion of syn-
chronization ; the various list operations, while all synchronized , use different locks,
which means that putIfAbsent is not atomic relative to other operations on the List . So
there is no guarantee that another thread won't modify the list while putIfAbsent is ex-
ecuting.
To make this approach work, we have to use the same lock that the List uses by using
client-side locking or external locking . Client-side locking entails guarding client code that
uses some object X with the lock X uses to guard its own state. In order to use client-side
locking, you must know what lock X uses.
The documentation for Vector and the synchronized wrapper classes states, albeit obli-
quely, that they support client-side locking, by using the intrinsic lock for the Vector or the
wrapper collection (not the wrapped collection). Listing 4.15 shows a putIfAbsent oper-
ation on a thread-safe List that correctly uses client-side locking.
Listing 4.15. Implementing Put-if-absent with Client-side Locking.
Search WWH ::




Custom Search