The fundamental problem in the previous program was that there were two threads modifying the fields of the same object. Furthermore the order in which the fields were modified is indeterminate.
There are a number of possible solutions to this problem. Not
all solutions are valid in all situations. For example, one of the
simplest and most direct is to make the object
immutable; that is, not to allow it to change after it's been
constructed. You can guarantee this by making all fields private,
not providing any setter methods, and not allowing any
non-constructor method in the class to change the value of a field.
However, this solution is inappropriate for this problem because
the count()
method must change the field
count
.
You can do a similar thing by declaring fields to be
final
. This way they can't be changed after the object is
constructed. This isn't always practical, however.
In this example, it would be simple to make count
a
local variable instead of a field. This is a relatively uncommon
solution (why?), but it does work for this case, primarily because
this is a toy example.
public class Counter {
public void count() {
int count = 0;
int limit = 100;
while (count++ != limit) System.out.println(count);
}
}
By making count
a local variable instead of a field, each
thread that invokes the count()
method on this object
gets a separate and different count
. Each time a method is
called, a separate stack frame is set up for its variables and
arguments. Different invocations of a method do not share
variables. However this has changed the meaning of the program. Now
each thread counts from 0 to 100. If this is what was originally
intended this is fine. However if the intention was for the first
thread to count from 0 to 100 and the second thread to count from
101 to 200, then this solution's no good.