Java Reference
In-Depth Information
atBats++;
}
This method looks like it can survive being called by multiple threads at the same time. It is
just incrementing some counters, so the order in which it is called by two different threads
won't matter. Indeed, it doesn't matter if one thread increments the hits counter, then anoth-
er thread increments that counter and the atBats counter, and then the first increments the
atBats counter. Even though there is an interweaving of the instructions, the results are the
same.
So we seem to be OK, except that we have made two assumptions that, if they are not true,
will cause us trouble. The first assumption is that the implementation of the Batter interface
that we get when we call asBatter() on a Player object will in fact be a BatterImpl . We
could check this (using a call to instanceof ), but that defeats the idea of using an interface
as the return value of the call asBatter() . That idea is to allow alternate implementations of
the interface. But if we are allowing alternate implementations, we can't decide on the safety
of our system through inspection of one of the implementations, unless we have specified the
concurrency behavior as part of the interface (which we have not).
The second assumption is somewhat subtler, but can lead to just as much trouble. Even if we
have the implementation shown earlier, we have to assume that the increment operations are
atomic if we are going to avoid worry about multithreading. That is, we have to assume that
an operation like atBats++ happens without interruption. But that is going to depend on how
the virtual machine is implemented. All we know is that an operation like atBats++ is equi-
valent to the series of operations:
temp = atBats;
temp = temp + 1;
atBats = temp;
To see why this is a problem in an environment with multiple threads, consider the schedule
where thread 1 comes in, sets temp to the value in atBats , increments the value of temp by 1,
and then is stopped for some reason. Thread 2 then executes the entire sequence, starting by
setting the value of temp to the current value of atBats . Thread 1 then begins again, assigning
the value of temp to atBats . The effect of this schedule is to increment atBats by 1. But the
correct result is to increment it by 2.
Search WWH ::




Custom Search