Proper synchronization is the key, but using AtomicInteger is not the whole answer. What you need to understand is that each thread must report a counter that has just been decreased, which can be changed by another thread, even if you: 1) use AtomicInteger or 2) correctly (separately), synchronizing both decrement and getCount .
The body of the while is a critical section, a section of code that should not be interrupted.
public void run(){ while( count > 0){ synchronized (Person.class) { decrement(); System.out.print(getCount() + ","); } } }
Output:
9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4
Sometimes it stops at -3 . Now each instance can freely continue and decrease, because it checks the while condition that passes, then the thread is interrupted, then the other thread is reduced. Then the original thread decreases, even if it is already up to 0 ! Check inside the loop.
public void run(){ while( count > 0){ synchronized (Person.class) { if (count > 0) { decrement(); System.out.print(getCount() + ","); } } } }
source share