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
ation on a thread-safe
List
that correctly uses client-side locking.
Listing 4.15. Implementing Put-if-absent with Client-side Locking.