views:

96

answers:

4

Hi - I know that concurrently accessing the same object from different threads, without synchronisation, is in general a bad thing. But what about this case:

I have multiple threads running (consider two, ThreadA & ThreadB). I also have this static class to keep count of the number of times a Thread does something.

public class Counter {
  static private int counter=0;
  static public void incCounter() {
    counter++;
  }
}

What happens if ThreadA and ThreadB both call Counter.incCounter()?

+9  A: 

It's not safe.

Each thread will attempt to read counter, add one to it, and write back the result. You're not guaranteed what order these reads and writes happen in, or even if the results are visible to each thread.

In particular, one failure case would be that each thread reads the value 0, increments it to 1, and writes back the value 1. This would give the counter the value 1 even after two threads attempted to increment it.

Consider using AtomicInteger.incrementAndGet() instead.

Dave L.
Huh, never knew it existed. Every day's a school day on SO. Thanks.
Kevin
A: 

It doesn't matter whether it's a static object or an instance: if you change it from multiple threads, you're going to have a problem.

Karmastan
+1  A: 

Its value will either be 1 or 2. There's no difference between static and non static variables in this context.

abyx
A: 

to avoid conflict use the keyword synchronized.

public class Counter {
  static private int counter=0;
  public static synchronized void incCounter() {
      counter++;
  }
}

this keywords allows only one thread for time to call incCounter().

Maverick-F14
This will work but is inefficient compared to `AtomicInteger`.
finnw