Counter
class Counter { private int c = 0; public void increment() { c++; } public void decrement() { c--; } public int value() { return c; } }
Counter
is designed so that each invocation of
increment
will add 1 to c
, and each
invocation of decrement
will subtract 1 from
c
. However, if a Counter
object is
referenced from multiple threads, interference between threads may
prevent this from happening as expected.
Interference happens when two operations, running in different threads, but acting on the same data, interleave. This means that the two operations consist of multiple steps, and the sequences of steps overlap.
It might not seem possible for operations on instances of
Counter
to interleave, since both operations on
c
are single, simple statements. However, even simple
statements can translate to multiple steps by the virtual machine.
We won't examine the specific steps the virtual machine takes —
it is enough to know that the single expression c++
can
be decomposed into three steps:
c
.
c
.
c--
can be decomposed the same way, except
that the second step decrements instead of increments.
Suppose Thread A invokes increment
at about the same
time Thread B invokes decrement
. If the initial value of
c
is 0
, their interleaved
actions might follow this sequence: