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 i
.
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 i
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 i = 0;
int limit = 100;
while (i++ != limit) System.out.println(i);
}
}
By making i
a local variable instead of a field, each thread that invokes
the count()
method on this object gets a separate and different i
. 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.