Java Reference
In-Depth Information
breaks in and starts writing its output. The exact order in which one thread preempts
the other threads is indeterminate. You'll probably see slightly different output every
time you run this program.
You need a way to assign exclusive access to a shared resource to one thread for a specific
series of statements. In this example, that shared resource is
System.out
, and the stateā
ments that need exclusive access are:
System
.
out
.
print
(
input
+
": "
);
System
.
out
.
print
(
DatatypeConverter
.
printHexBinary
(
digest
));
System
.
out
.
println
();
Synchronized Blocks
To indicate that these five lines of code should be executed together, wrap them in a
synchronized
block that synchronizes on the
System.out
object, like this:
synchronized
(
System
.
out
)
{
System
.
out
.
print
(
input
+
": "
);
System
.
out
.
print
(
DatatypeConverter
.
printHexBinary
(
digest
));
System
.
out
.
println
();
}
Once one thread starts printing out the values, all other threads will have to stop and
wait for it to finish before they can print out their values. Synchronization forces all
code that synchronizes on the same object to run in series, never in parallel. For instance,
if some other code in a different class and different thread also happened to synchronize
on
System.out
, it too would not be able to run in parallel with this block. However,
other code that synchronizes on a different object or doesn't synchronize at all can still
run in parallel with this code. It can do so even if it also uses
System.out
. Java provides
no means to stop all other threads from using a shared resource. It can only prevent
other threads that synchronize on the same object from using the shared resource.
In fact, the
PrintStream
class internally synchronizes most methods
on the
PrintStream
object (
System.out
, in this example). In other
words, every other thread that calls
System.out.println()
will be
synchronized on
System.out
and will have to wait for this code to
finish.
PrintStream
is unique in this respect. Most other
Output
Stream
subclasses do not synchronize themselves.
Synchronization must be considered any time multiple threads share resources. These
threads may be instances of the same
Thread
subclass or use the same
Runnable
class,
or they may be instances of completely different classes. The key is the resources they
share, not what classes they are. Synchronization becomes an issue only when two
threads both possess references to the same object. In the previous example, the problem