问题
I am trying to count how many instances of a class generated during the run time of a process under multi-threading environment. The way how I do it is to increase a static counter in the constructor by looking at this post: How to Count Number of Instances of a Class
So in multi-threading environment, here is how i define the class:
class Television {
private static volatile int counter = 0;
public Television(){
counter ++;
}
}
However, I am not sure whether there is a potential bug with the code above since I think constructor in java does not imply synchronization and counter++
is not atomic so if two threads are creating instances simultaneously, is the code a bug somehow? but I am not quite sure yet.
回答1:
There is a bug in this code (specifically, a race condition), because the read of counter and write to counter aren't atomically executed.
In other words, two threads can read the same value of counter
, increment that value, and then write the same value back to the variable.
Thread 1 Thread 2
======== ========
Read 0
Read 0
Increment
Increment
Write 1
Write 1
So the value would be 1, not 2, afterwards.
Use AtomicInteger
and AtomicInteger.incrementAndGet()
instead.
回答2:
As counter++
is NOT atomic, you can replace it with JDK's AtomicInteger
which is threadsafe.
You can AtomicInteger
's use getAndIncrement()
method as shown below:
class Television {
private static final AtomicInteger counter = new AtomicInteger();
public Television(){
counter.getAndIncrement();
}
}
An AtomicInteger is used in applications such as atomically incremented counters, and cannot be used as a replacement for an Integer.
You can look here
回答3:
There are two ways here to bypass the underlying "++ on int" not being an atomic operation:
A) as others suggested, use AtomicInteger
B) introduce a common LOCK that all ctors can be using to sync on; like:
private final static Object LOCK = new Object();
public Television() {
synchronized (LOCK) {
counter++;
}
来源:https://stackoverflow.com/questions/40597894/count-number-of-instances-of-a-class-in-multi-threading-environment