javaatomicinteger

Atomic Integers values are not getting updated in threads


I have defined an atomicinterger variable in class. The class also extends thread class .I have created two threads and incrementing the value of the atomic integer in run method .I was excepting the value of 2 after running two threads, But I am getting value as 1. Please let me know what went wrong in the below code.

public class AtomicIntergerTest extends Thread {

    AtomicInteger i = new AtomicInteger();
    int j = 0;

    @Override
    public void run() {
        i.incrementAndGet();

    }

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub

        AtomicIntergerTest th1 = new AtomicIntergerTest();

        AtomicIntergerTest th2 = new AtomicIntergerTest();

        th1.start();
        th2.start();
        th1.join();
        th2.join();

        System.out.println(th2.i.get());

    }

}

Solution

  • You said:

    I am still confused if have have a static integer i can get the same data visible across the all threads with that i can achieve my thread safety

    You misunderstand. No you can't.

    The VM basically works like this:

    For any given field, all threads have a local copy of that field, and they all have an unfair coin. They flip it anytime they read or write to it. If the coin lands heads, they sync the field and read/write it. If the coin lands tails, they read/write the copy. The coin is unfair, in that it will mess with you: Always flip heads during tests and on your machine, flip tails a few times juuuuust when giving a demo to that important customer.

    Thus, if we have this code running in one thread:

    x = x + 1;
    

    and the same code in another thread, x may only increment once, because the second thread read it's clone copy and thus the first thread's increment is missed. Or not. Maybe today you tried 100 times and the number ended up +2 every time. And then the next song on your winamp starts or the phase of the moon changes and now it seems to reliably add only 1. It can all happen, which is why such code is fundamentally broken. You should not interact with a field from multiple threads unless you've taken great care to streamline it.

    You cannot force the coin, unless you establish so-called comes-before or comes-after relationships. You do this by using volatile or synchronized, or by calling code that does that. It gets complicated. Quickly.

    AtomicInteger is a different solution. It is, well, atomic. If you have a thread with:

    atomicInt.incrementAndGet();
    

    and another one with the same thing, after they've both ran, that atomicInt has been incremented by 2, guaranteed.