Java Reference
In-Depth Information
was that several threads had access to the same
PrintStream
object,
System.out
. In this
case, it was a static class variable that led to the conflict. However, instance variables can
also have problems.
For example, suppose your web server keeps a logfile. The logfile may be represented
by a class like the one shown in
Example 3-11
. This class itself doesn't use multiple
threads. However, if the web server uses multiple threads to handle incoming connecā
tions, then each of those threads will need access to the same logfile and consequently
to the same
LogFile
object.
Example 3-11. LogFile
import
java.io.*
;
import
java.util.*
;
public
class
LogFile
{
private
Writer
out
;
public
LogFile
(
File
f
)
throws
IOException
{
FileWriter
fw
=
new
FileWriter
(
f
);
this
.
out
=
new
BufferedWriter
(
fw
);
}
public
void
writeEntry
(
String
message
)
throws
IOException
{
Date
d
=
new
Date
();
out
.
write
(
d
.
toString
());
out
.
write
(
'\t'
);
out
.
write
(
message
);
out
.
write
(
"\r\n"
);
}
public
void
close
()
throws
IOException
{
out
.
flush
();
out
.
close
();
}
}
In this class, the
writeEntry()
method finds the current date and time, then writes into
the underlying file using four separate invocations of
out.write()
. A problem occurs
if two or more threads each have a reference to the same
LogFile
object and one of
those threads interrupts another in the process of writing the data. One thread may
write the date and a tab, then the next thread might write three complete entries; then,
the first thread could write the message, a carriage return, and a linefeed. The solution,
once again, is synchronization. However, here there are two good choices for which
object to synchronize on. The first choice is to synchronize on the
Writer
object
out
.
For example: