Home > other >  understand thread interference (Java)
understand thread interference (Java)

Time:09-13

I'm trying to understand what thread interference is. This is an explanation about thread interference from Java official site.

Thread A: Retrieve c.
Thread B: Retrieve c.
Thread A: Increment retrieved value; result is 1.
Thread B: Decrement retrieved value; result is -1.
Thread A: Store result in c; c is now 1.
Thread B: Store result in c; c is now -1.

so I added codes to see c's changes.

In the picture(4th line), Shouldn't 1th decrement:(Retrieve C) 0 be -1? why it's 0?

Also, if you see this below result, 2th decrement:(Retrieve C) is -1.

I think 2th decrement(Decreased C) should be -2, but it's still -1.

I don't understand. Can someone explain my reslt?

2th decrement:(Retrieve C) -1

2th decrement(Decreased C) -1

enter image description here

public class Counter {
private int c = 0;
public void increment(){
    for(int i=0; i<1000; i  ){
        System.out.println(i   "th increment:(Retrieve  C) "   c);
        c  ;
        System.out.println(i   "th increment:(Increased C) "   c);
    }
}
public void decrement(){
    for(int i=0; i<1000; i  ){
        System.out.println(i   "th decrement:(Retrieve  C) "   c);
        c--;
        System.out.println(i   "th decrement(Decreased C) "   c);
    }
}
public int getC(){
    return c;
}

public static void main(String[] args) throws InterruptedException{
    Counter c = new Counter();
    Thread t1 = new Thread(() -> {
        c.increment();
    });
    Thread t2 = new Thread(() -> {
        c.decrement();

    });

    t1.start();
    t2.start();

    t1.join();
    t2.join();

}

}

CodePudding user response:

The line c ; actually does three things, one after the other.

  1. It reads the value of c.
  2. It increments what it saw.
  3. It saves the new value back into c.

The operations is not atomic, which means there's no guarantee that c won't change independently while it's doing that. Likewise for c--;.

So while you've got two threads doing similar things to the same variable c, it's very likely that one of them is going to change c while the other is doing its work. And that seems to be what you're seeing.

In fact, by printing c in both threads, you're increasing the likelihood that one of the threads will change the value of c between the times when the other thread prints its two messages.

CodePudding user response:

The term 'interference' has no official meaning. Your code is suffering from 2 problems

  1. race condition: because the read and write aren't atomic, and therefore you can run into lost updates.

  2. data race: because the access to the 'c' variable isn't synchronized, there is no happens-before edge. To gain a deeper understanding, you need to dig into the Java Memory Model.

Both problems can easily be solved by making 'c' an AtomicInteger and use the increment/decrement methods.

  • Related