Java Reference
In-Depth Information
closed inner objects. An inner class that needs to synchronize with its
enclosing object must do so explicitly and a
synchronized
statement is
a perfect toolthe alternative is to declare a synchronized method in the
enclosing class just for the inner class to use.
If you need a
synchronized
statement to use the same lock used by static
synchronized methods, you can use the class literal for your class (see
example below). This also applies if you need to protect access to static
data from within non-static code. For example, consider the
Body
class.
It maintains a static field,
nextID
, to hold the next identifier for a new
Body
object. That field is accessed in the
Body
class's no-arg constructor.
If
Body
objects were created concurrently, interference could occur when
the
nextID
field is updated. To prevent that from happening you can use
a
synchronized
statement within the
Body
constructor that uses the lock
of the
Body.class
object:
Body() {
synchronized (Body.class) {
idNum = nextID++;
}
}
The
synchronized
statement in the constructor acquires the lock of the
Class
object for
Body
in the same way a
synchronized
static method of the
class would. Synchronizing on
this
would use a different object for each
invocation and so would not prevent threads from accessing
nextID
con-
currently. It would also be wrong to use the
Object
method
getClass
to
retrieve the
Class
object for the current instance: In an extended class,
such as
AttributedBody
, that would return the
Class
object for
Attrib-
utedBody
not
Body
, and so again, different locks would be used and inter-
ference would not be prevented. The simplest rule is to always protect
access to static data using the lock of the
Class
object for the class in
which the static data was declared.
In many cases, instead of using a
synchronized
statement you can factor
the code to be protected into a
synchronized
method of its own. You'll