Java Reference
In-Depth Information
public
void
writeEntry
(
String
message
)
throws
IOException
{
synchronized
(
out
)
{
Date
d
=
new
Date
();
out
.
write
(
d
.
toString
());
out
.
write
(
'\t'
);
out
.
write
(
message
);
out
.
write
(
"\r\n"
);
}
}
This works because all the threads that use this
LogFile
object also use the same
out
object that's part of that
LogFile
. It doesn't matter that
out
is private. Although it is used
by the other threads and objects, it's referenced only within the
LogFile
class. Further‐
more, although you're synchronizing here on the
out
object, it's the
writeEntry()
method that needs to be protected from interruption. The
Writer
classes all have their
own internal synchronization, which protects one thread from interfering with a
write()
method in another thread. (This is not true of input and output streams, with
the exception of
PrintStream
. It is possible for a write to an output stream to be inter‐
rupted by another thread.) Each
Writer
class has a
lock
field that specifies the object
on which writes to that writer synchronize.
The second possibility is to synchronize on the
LogFile
object itself. This is simple
enough to arrange with the
this
keyword. For example:
public
void
writeEntry
(
String
message
)
throws
IOException
{
synchronized
(
this
)
{
Date
d
=
new
Date
();
out
.
write
(
d
.
toString
());
out
.
write
(
'\t'
);
out
.
write
(
message
);
out
.
write
(
"\r\n"
);
}
}
Synchronized Methods
Because synchronizing the entire method body on the object itself is such a common
thing to do, Java provides a shortcut. You can synchronize an entire method on the
current object (the
this
reference) by adding the
synchronized
modifier to the method
declaration. For example:
public
synchronized
void
writeEntry
(
String
message
)
throws
IOException
{
Date
d
=
new
Date
();
out
.
write
(
d
.
toString
());
out
.
write
(
'\t'
);
out
.
write
(
message
);
out
.
write
(
"\r\n"
);
}