|
See the following code:
Unsafe Counter
public class Counter implements Counting
{
private int value = 0;
public int incrementAndGet()
{
return this.value++;
}
public int decrementAndGet()
{
return this.value--;
}
}
CounterClient
public class CounterClient implements Runnable
{
private Counting counter;
public CounterClient(Counting counter)
{
this.counter = counter;
}
public void run()
{
while(true)
{
System.out.println("Incrementing from " + Thread.currentThread().getName() );
System.out.println("Counter value in " + Thread.currentThread().getName() + " = " + counter.incrementAndGet());
try
{
Thread.sleep(2000L);
} catch (InterruptedException ex)
{
Logger.getLogger(CounterClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
TestCounter
public class TestCounter
{
public static void main(String args[])
{
Counter counter = new Counter();
SafeCounter safeCounter = new SafeCounter();
Executor exec = Executors.newCachedThreadPool();
exec.execute(new CounterClient(counter));
exec.execute(new CounterClient(counter));
}
}
I did a test run for this code and one of the outputs was this:
Incrementing from pool-1-thread-1
Incrementing from pool-1-thread-2
Counter value in pool-1-thread-1 = 0
Counter value in pool-1-thread-2 = 1
Incrementing from pool-1-thread-2
Incrementing from pool-1-thread-1
Counter value in pool-1-thread-2 = 2
Counter value in pool-1-thread-1 = 3
Incrementing from pool-1-thread-2
Incrementing from pool-1-thread-1
Counter value in pool-1-thread-1 = 4
Counter value in pool-1-thread-2 = 5
Incrementing from pool-1-thread-2
Incrementing from pool-1-thread-1
Counter value in pool-1-thread-1 = 6
Counter value in pool-1-thread-2 = 7
Incrementing from pool-1-thread-1
Counter value in pool-1-thread-1 = 8
Incrementing from pool-1-thread-2
Counter value in pool-1-thread-2 = 9
Incrementing from pool-1-thread-2
Counter value in pool-1-thread-2 = 10
Incrementing from pool-1-thread-1
Counter value in pool-1-thread-1 = 11
Incrementing from pool-1-thread-1
Incrementing from pool-1-thread-2
Counter value in pool-1-thread-2 = 13
Counter value in pool-1-thread-1 = 12
I am trying to understand what exactly is going on in the thread activity here that is not thread safe. As you can see, some values are out of order: e.g. 13,12
This is what I can deduct from the output:
Thread-1 increments (value++)
Thread-2 increments (value++)
Thread-1's value should be 1 now, but I see this:
Counter value in pool-1-thread-1 = 0
Is this because thread-1 is still reading and didn't write the result of the register back to memory?
Why is it 0? Didn't it just increment?
Thread-2's value is 1. That's logical.
This is all a bit confusing to me and I would like to know exactly what's going on in that output.
Thanks
|
|
|
|
|
The code you have will return the value then increment, or decrement. To perform the change before hand try:
return ++this.value;
It is not really thread safe, but it is such a trivial example that you won't see a problem.
Panic, Chaos, Destruction. My work here is done.
Drink. Get drunk. Fall over - P O'H
OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre
I cannot live by bread alone. Bacon and ketchup are needed as well. - Trollslayer
Have a bit more patience with newbies. Of course some of them act dumb - they're often *students*, for heaven's sake - Terry Pratchett
|
|
|
|