2

I am trying to understand volatile usage by the below example. I expect it to print 10 first and then 15 second. But most of the time i end getting 10 and 10. Is some thing with the below code itself.

class T implements Runnable {

    private volatile int x = 10;

    @Override
    public void run() {
        if(x==10) {
            System.out.println(x);
            x = x+ 5;
        } else if(x==15) {
            System.out.println(x);
        }
    }
}


public class Prep {

    public static void main(String [] args) {
        T t1 = new T();
        new Thread(t1).start();
        new Thread(t1).start();
    }
}
0

2 Answers 2

7

You just have a race condition: both threads run in parallel, and thus you have (for example)

  • thread 1 tests if x == 10 (true)
  • thread 2 tests if x == 10 (true)
  • thread 1 prints 10
  • thread 2 prints 10
  • ...

The fact that x is volatile here is irrelevant. The only thing that volatile guarantees in this example is that if thread 1 has already incremented x when thread 2 reads its value, then thread 2 will see the incremented value. But it doesn't mean that the two threads can't run in parallel as shown above.

Sign up to request clarification or add additional context in comments.

3 Comments

@user3801948 Locking or immutability
@user3801948 - You have actually shared it.. You have not considered the fact that the statements inside the if block aren't guaranteed to execute together for a thread.
The problem is not sharing. The variable is shared. The problem is mutual exclusion. If you want a single thread to execute the run() method at a time, then it should be synchronized.
0

This will work :

public static void main(String[] args) {
        T t1 = new T();
        new Thread(t1).start();
        try {
            Thread.currentThread().sleep(1000); // sleeping for sometime .
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        new Thread(t1).start();
    }

answer : 10 15

Reason : The operations

if(x==10) {
            System.out.println(x);

might have executed first for the first thread, then context would have switched back to Thread2 (race condition as JB Nizet explains..) so when both threads print the value of x, it is still 10.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.