1

I have two threads updating a shared int at the same time. Most of times, this code will print 0 and 1. But some times, it will print 0 and 0 (one update failed). If I make the int value volatile, will fix that update fail, once for all?

This is not a Home-Work question, really. I just wrote these code and this question, like if was, to clarify my understanding of Java Memory Model. I read this Article.

I know this code will be fixed in a synchronized way, but this is not the scope of question, is just about the volatile will fix or not, and why.

    public class Testes{

    public static int value = 0;

    public static void main(String ... args) {

        T t = new T();
        T t2 = new T();

        t.start();
        t2.start();

    }

}

class T extends Thread{

    public void update(){
        System.out.println(Testes.value++);
    }

    public void run(){
        this.update();
    }

}
Svetlin Zarev
  • 14,713
  • 4
  • 53
  • 82
G Bisconcini
  • 764
  • 2
  • 6
  • 25
  • Have you tried testing your code by setting int value volatile? – Santanu C May 06 '15 at 02:36
  • @santaunu yes, but really, you must run lots of times. I don't know if I run so much times to see if it will fix, or not. To get this 0 and 0 result, I run around 450 times... LOL! – G Bisconcini May 06 '15 at 02:39
  • 1
    @yngwietiger I'm not sure, because you have the Java Memory Model, and `volatile` will fix the Java Memory Model problem, but the process of `value++` is not atomic and it can be broken in more, and the thread 1 will race with thread 2 – G Bisconcini May 06 '15 at 02:44
  • @yngwietiger , yes, I probably will never use `volatile`, but this is more about learning the Java Memory Model. I found this question on where to use the `volatile`. http://stackoverflow.com/questions/5816790/the-code-example-which-can-prove-volatile-declare-should-be-used – G Bisconcini May 06 '15 at 03:06

2 Answers2

3

If I make the int value volatile, will fix that update fail, once for all?

No. The issue you are seeing is almost certainly not related to memory inconsistency. The failure is because of atomicity. It is widely known ++ operator is not atomic (it is actually three operations). There is plenty of information you can read on about it.

John Vint
  • 39,695
  • 7
  • 78
  • 108
  • Did you know where can I found a good example of this situation where `volatile` will fix the problem? A example code. tnx! – G Bisconcini May 06 '15 at 02:55
  • 1
    Well, unfortunately `volatile` cannot fix this problem for you. It can only deal with a single operation. If you really want to resolve this you can either use `synchronized` (as you mentioned) or the more appropriate `AtomicInteger` class. The `AtomicInteger` can be `final` so you could completely disregard `volatile` in that case. – John Vint May 06 '15 at 02:57
  • 1
    Yes, I understand that. But I meant a code situation, an example, where I will put the `volatile` and will fix. A code example.. I googled, but i don't found – G Bisconcini May 06 '15 at 02:59
  • 1
    I have found! http://stackoverflow.com/questions/5816790/the-code-example-which-can-prove-volatile-declare-should-be-used – G Bisconcini May 06 '15 at 03:00
0

Thanks to John for clarifying the same...

When you execute System.out.println(Testes.value++) what happens is it is a postfix operation for increment...so the println is done first and then value gets incremented...thats why you see 0 by the first thread..but after the println is done its execution the value is now 1 ..that is why the second thread shows 1 when it prints the value ....

acearch
  • 343
  • 1
  • 8