Java Reference
In-Depth Information
Simply adding the synchronized modifier to all methods is not a catchall solution for
synchronization problems. For one thing, it exacts a severe performance penalty in
many VMs (though more recent VMs have improved greatly in this respect), potentially
slowing down your code by a factor of three or more. Second, it dramatically increases
the chances of deadlock. Third, and most importantly, it's not always the object itself
you need to protect from simultaneous modification or access, and synchronizing on
the instance of the method's class may not protect the object you really need to protect.
For instance, in this example, what you're really trying to prevent is two threads simul‐
taneously writing onto out . If some other class had a reference to out completely un‐
related to the LogFile , this attempt would fail. However, in this example, synchronizing
on the LogFile object is sufficient because out is a private instance variable. Because
you never expose a reference to this object, there's no way for any other object to invoke
its methods except through the LogFile class. Therefore, synchronizing on the Log
File object has the same effect as synchronizing on out .
Alternatives to Synchronization
Synchronization is not always the best solution to the problem of inconsistent behavior
caused by thread scheduling. There are a number of techniques that avoid the need for
synchronization entirely. The first is to use local variables instead of fields wherever
possible. Local variables do not have synchronization problems. Every time a method
is entered, the virtual machine creates a completely new set of local variables for the
method. These variables are invisible from outside the method and are destroyed when
the method exits. As a result, it's impossible for one local variable to be shared by two
different threads. Every thread has its own separate set of local variables.
Method arguments of primitive types are also safe from modification in separate threads
because Java passes arguments by value rather than by reference. A corollary of this is
that pure functions such as Math.sqrt() that take zero or more primitive data type
arguments, perform some calculation, and return a value without ever interacting with
the fields of any class are inherently thread safe. These methods often either are or should
be declared static.
Method arguments of object types are a little trickier because the actual argument passed
by value is a reference to the object. Suppose, for example, you pass a reference to an
array into a sort() method. While the method is sorting the array, there's nothing to
stop some other thread that also has a reference to the array from changing the values
in the array.
String arguments are safe because they're immutable (i.e., once a String object has
been created, it cannot be changed by any thread). An immutable object never changes
state. The values of its fields are set once when the constructor runs and never altered
thereafter. StringBuilder arguments are not safe because they're not immutable; they
can be changed after they're created.
Search WWH ::




Custom Search