The code example which can prove “volatile” declare should be used











up vote
14
down vote

favorite
5












Currently I can't understand when we should use volatile to declare variable.



I have do some study and searched some materials about it for a long time and know that when a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations.



However, I still can't understand in what scenario we should use it. I mean can someone provide any example code which can prove that using "volatile" brings benefit or solve problems compare to without using it?










share|improve this question




















  • 6




    volatile (and many other concurrency-related aspects) are very hard to demonstrate, because if you use them wrongly, then they may still appear to work correctly and not show a problem until a very specific condition occurs and leads to a problem.
    – Joachim Sauer
    Apr 28 '11 at 10:05










  • I have tried this myself and produced a test which passes values between threaded using a non-voltile field one billion times successfully, however fails relatively quickly when the same box is loaded. Even timing the performance impact of volatile is very difficult are it depends on lots of factors.
    – Peter Lawrey
    Apr 28 '11 at 10:24










  • Have a look at this post: stackoverflow.com/questions/7855700/…
    – Ravindra babu
    May 10 at 12:12















up vote
14
down vote

favorite
5












Currently I can't understand when we should use volatile to declare variable.



I have do some study and searched some materials about it for a long time and know that when a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations.



However, I still can't understand in what scenario we should use it. I mean can someone provide any example code which can prove that using "volatile" brings benefit or solve problems compare to without using it?










share|improve this question




















  • 6




    volatile (and many other concurrency-related aspects) are very hard to demonstrate, because if you use them wrongly, then they may still appear to work correctly and not show a problem until a very specific condition occurs and leads to a problem.
    – Joachim Sauer
    Apr 28 '11 at 10:05










  • I have tried this myself and produced a test which passes values between threaded using a non-voltile field one billion times successfully, however fails relatively quickly when the same box is loaded. Even timing the performance impact of volatile is very difficult are it depends on lots of factors.
    – Peter Lawrey
    Apr 28 '11 at 10:24










  • Have a look at this post: stackoverflow.com/questions/7855700/…
    – Ravindra babu
    May 10 at 12:12













up vote
14
down vote

favorite
5









up vote
14
down vote

favorite
5






5





Currently I can't understand when we should use volatile to declare variable.



I have do some study and searched some materials about it for a long time and know that when a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations.



However, I still can't understand in what scenario we should use it. I mean can someone provide any example code which can prove that using "volatile" brings benefit or solve problems compare to without using it?










share|improve this question















Currently I can't understand when we should use volatile to declare variable.



I have do some study and searched some materials about it for a long time and know that when a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations.



However, I still can't understand in what scenario we should use it. I mean can someone provide any example code which can prove that using "volatile" brings benefit or solve problems compare to without using it?







java multithreading concurrency volatile






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 28 '11 at 10:04









Joachim Sauer

231k48478558




231k48478558










asked Apr 28 '11 at 9:56









Eric Jiang

268519




268519








  • 6




    volatile (and many other concurrency-related aspects) are very hard to demonstrate, because if you use them wrongly, then they may still appear to work correctly and not show a problem until a very specific condition occurs and leads to a problem.
    – Joachim Sauer
    Apr 28 '11 at 10:05










  • I have tried this myself and produced a test which passes values between threaded using a non-voltile field one billion times successfully, however fails relatively quickly when the same box is loaded. Even timing the performance impact of volatile is very difficult are it depends on lots of factors.
    – Peter Lawrey
    Apr 28 '11 at 10:24










  • Have a look at this post: stackoverflow.com/questions/7855700/…
    – Ravindra babu
    May 10 at 12:12














  • 6




    volatile (and many other concurrency-related aspects) are very hard to demonstrate, because if you use them wrongly, then they may still appear to work correctly and not show a problem until a very specific condition occurs and leads to a problem.
    – Joachim Sauer
    Apr 28 '11 at 10:05










  • I have tried this myself and produced a test which passes values between threaded using a non-voltile field one billion times successfully, however fails relatively quickly when the same box is loaded. Even timing the performance impact of volatile is very difficult are it depends on lots of factors.
    – Peter Lawrey
    Apr 28 '11 at 10:24










  • Have a look at this post: stackoverflow.com/questions/7855700/…
    – Ravindra babu
    May 10 at 12:12








6




6




volatile (and many other concurrency-related aspects) are very hard to demonstrate, because if you use them wrongly, then they may still appear to work correctly and not show a problem until a very specific condition occurs and leads to a problem.
– Joachim Sauer
Apr 28 '11 at 10:05




volatile (and many other concurrency-related aspects) are very hard to demonstrate, because if you use them wrongly, then they may still appear to work correctly and not show a problem until a very specific condition occurs and leads to a problem.
– Joachim Sauer
Apr 28 '11 at 10:05












I have tried this myself and produced a test which passes values between threaded using a non-voltile field one billion times successfully, however fails relatively quickly when the same box is loaded. Even timing the performance impact of volatile is very difficult are it depends on lots of factors.
– Peter Lawrey
Apr 28 '11 at 10:24




I have tried this myself and produced a test which passes values between threaded using a non-voltile field one billion times successfully, however fails relatively quickly when the same box is loaded. Even timing the performance impact of volatile is very difficult are it depends on lots of factors.
– Peter Lawrey
Apr 28 '11 at 10:24












Have a look at this post: stackoverflow.com/questions/7855700/…
– Ravindra babu
May 10 at 12:12




Have a look at this post: stackoverflow.com/questions/7855700/…
– Ravindra babu
May 10 at 12:12












6 Answers
6






active

oldest

votes

















up vote
13
down vote



accepted










Here is an example of why volatile is necessary. If you remove the keyword volatile, thread 1 may never terminate. (When I tested on Java 1.6 Hotspot on Linux, this was indeed the case - your results may vary as the JVM is not obliged to do any caching of variables not marked volatile.)



public class ThreadTest {
volatile boolean running = true;

public void test() {
new Thread(new Runnable() {
public void run() {
int counter = 0;
while (running) {
counter++;
}
System.out.println("Thread 1 finished. Counted up to " + counter);
}
}).start();
new Thread(new Runnable() {
public void run() {
// Sleep for a bit so that thread 1 has a chance to start
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {
// catch block
}
System.out.println("Thread 2 finishing");
running = false;
}
}).start();
}

public static void main(String args) {
new ThreadTest().test();
}
}





share|improve this answer























  • Sorry, I tried to remove "volatile" keyword and run the program for many times, but every time thread 1 can be terminated. I think for the code you provided even without "volatile" thread 1 can always be terminated every time.
    – Eric Jiang
    Apr 28 '11 at 10:40






  • 3




    @Eric: it gives the effect I describe on two different machines running Java 6 JVMs. I guess I should have phrased it differently. It is only guaranteed to terminate if the volatile keyword is present. If it's not present, the JVM is free to cache the value of running, so thread 1 need not terminate. However, it isn't forced to cache the value.
    – Simon Nickerson
    Apr 28 '11 at 11:25










  • Keeping "volatile" present will terminate thread 1 as soon as 'running' is set false in thread 2. But if remove "volatile", thread 1 may won't terminate even after 'running' is set false in thread2, when thread will terminate depends on when JVM update "running" value in thread 1. Do you mean that??? But if "running" has been set 'false' in thread 2, why thread1 can't get the right value??? If so I think JVM behave wrong.
    – Eric Jiang
    Apr 28 '11 at 11:53






  • 1




    The JVM is not behaving wrongly. Without volatile (or synchronization, or something else which forces a 'happens-before' relationship), thread 1 need not see the change made by thread 2.
    – Simon Nickerson
    Apr 28 '11 at 12:02






  • 2




    @Eric: that's exactly the problem: "correct behaviour" is not equivalent to "intuitive behaviour". JVMs are free to cache values (for example in the register of a CPU) if it is read repeatedly and need not read it from main memory each time. Specifying that a variable is volatile disables this caching!
    – Joachim Sauer
    Apr 28 '11 at 14:41


















up vote
4
down vote













The following is a canonical example of the necessity of volatile (in this case for the str variable. Without it, hotspot lifts the access outside the loop (while (str == null)) and run() never terminates. This will happen on most -server JVMs.



public class DelayWrite implements Runnable {
private String str;
void setStr(String str) {this.str = str;}

public void run() {
  while (str == null);
  System.out.println(str);
}

public static void main(String args) {
  DelayWrite delay = new DelayWrite();
  new Thread(delay).start();
  Thread.sleep(1000);
  delay.setStr("Hello world!!");
}
}





share|improve this answer























  • Wesley: Thank you very much!!! I can see the issue with java -server to start JVM and run the app. Now I get my answer, thanks!
    – Eric Jiang
    Apr 29 '11 at 3:20










  • new Thread(fun).start(); this line should be new Thread(delay).start(); correct ?
    – Dhanaraj Durairaj
    Feb 4 '15 at 9:00










  • yes, fixed. thx.
    – Jed Wesley-Smith
    Feb 4 '15 at 23:26










  • Great and useful! I have another questions, 1) Why you use 'canonical '? 2) How could I get the assembly code when the java code is running? can I get some clue from assembly, like other cpp code demonstrations?
    – gfan
    Mar 18 '17 at 11:09


















up vote
2
down vote













Eric, I have read your comments and one in particular strikes me




In fact, I can understand the usage of volatile on the concept
level. But for practice, I can't think
up the code which has concurrency
problems without using volatile




The obvious problem you can have are compiler reorderings, for example the more famous hoisting as mentioned by Simon Nickerson. But let's assume that there will be no reorderings, that comment can be a valid one.



Another issue that volatile resolves are with 64 bit variables (long, double). If you write to a long or a double, it is treated as two separate 32 bit stores. What can happen with a concurrent write is the high 32 of one thread gets written to high 32 bits of the register while another thread writes the low 32 bit. You can then have a long that is neither one or the other.



Also, if you look at the memory section of the JLS you will observe it to be a relaxed memory model.



That means writes may not become visible (can be sitting in a store buffer) for a while. This can lead to stale reads. Now you may say that seems unlikely, and it is, but your program is incorrect and has potential to fail.



If you have an int that you are incrementing for the lifetime of an application and you know (or at least think) the int wont overflow then you don't upgrade it to a long, but it is still possible it can. In the case of a memory visibility issue, if you think it shouldn't effect you, you should know that it still can and can cause errors in your concurrent application that are extremely difficult to identify. Correctness is the reason to use volatile.






share|improve this answer




























    up vote
    1
    down vote













    The volatile keyword is pretty complex and you need to understand what it does and does not do well before you use it. I recommend reading this language specification section which explains it very well.



    They highlight this example:



    class Test {
    static volatile int i = 0, j = 0;
    static void one() { i++; j++; }
    static void two() {
    System.out.println("i=" + i + " j=" + j);
    }
    }


    What this means is that during one() j is never greater than i. However, another Thread running two() might print out a value of j that is much larger than i because let's say two() is running and fetches the value of i. Then one() runs 1000 times. Then the Thread running two finally gets scheduled again and picks up j which is now much larger than the value of i. I think this example perfectly demonstrates the difference between volatile and synchronized - the updates to i and j are volatile which means that the order that they happen in is consistent with the source code. However the two updates happen separately and not atomically so callers may see values that look (to that caller) to be inconsistent.



    In a nutshell: Be very careful with volatile!






    share|improve this answer























    • From the link you provide, an example below: class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } "This allows method one and method two to be executed concurrently, but guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread" But I don't think the example is correct, using "volatile' or not has same result, j always has the chance to be different from i.
      – Eric Jiang
      Apr 28 '11 at 10:50












    • @Eric Jiang - The point is j can be greater than i. Although i is always incremented first. If both are volatile, they can still be different, but j can not be greater than i.
      – Ishtar
      Apr 28 '11 at 11:43










    • I've updated my answer to explain what i think the JLS is saying (although i think the JLS said it very well in the first place) :)
      – alpian
      Apr 28 '11 at 12:00










    • Thanks alpian, in fact, I can catch your meaning very well, but when I run the code and test for many many times I never see J is greater than i. Is it related to my PC environment, such as JDK version or hardware? Can I understand as that even the code is running for hundreds thousands of times there may be one time that J is greater than i (just has risk but maybe won't happen, so need to use 'volatile' to guarantee), right?
      – Eric Jiang
      Apr 29 '11 at 2:48


















    up vote
    0
    down vote













    A minimalist example in java 8, if you remove volatile keyword it will never end.



    public class VolatileExample {

    private static volatile boolean BOOL = true;

    public static void main(String args) throws InterruptedException {
    new Thread(() -> { while (BOOL) { } }).start();
    TimeUnit.MILLISECONDS.sleep(500);
    BOOL = false;
    }
    }





    share|improve this answer




























      up vote
      0
      down vote













      To expand on the answer from @jed-wesley-smith, if you drop this into a new project, take out the volatile keyword from the iterationCount, and run it, it will never stop. Adding the volatile keyword to either str or iterationCount would cause the code to end successfully. I've also noticed that the sleep can't be smaller than 5, using Java 8, but perhaps your mileage may vary with other JVMs / Java versions.



      public static class DelayWrite implements Runnable
      {
      private String str;
      public volatile int iterationCount = 0;

      void setStr(String str)
      {
      this.str = str;
      }

      public void run()
      {
      while (str == null)
      {
      iterationCount++;
      }
      System.out.println(str + " after " + iterationCount + " iterations.");
      }
      }

      public static void main(String args) throws InterruptedException
      {
      System.out.println("This should print 'Hello world!' and exit if str or iterationCount is volatile.");
      DelayWrite delay = new DelayWrite();
      new Thread(delay).start();
      Thread.sleep(5);
      System.out.println("Thread sleep gave the thread " + delay.iterationCount + " iterations.");
      delay.setStr("Hello world!!");
      }





      share|improve this answer





















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














         

        draft saved


        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5816790%2fthe-code-example-which-can-prove-volatile-declare-should-be-used%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        6 Answers
        6






        active

        oldest

        votes








        6 Answers
        6






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        13
        down vote



        accepted










        Here is an example of why volatile is necessary. If you remove the keyword volatile, thread 1 may never terminate. (When I tested on Java 1.6 Hotspot on Linux, this was indeed the case - your results may vary as the JVM is not obliged to do any caching of variables not marked volatile.)



        public class ThreadTest {
        volatile boolean running = true;

        public void test() {
        new Thread(new Runnable() {
        public void run() {
        int counter = 0;
        while (running) {
        counter++;
        }
        System.out.println("Thread 1 finished. Counted up to " + counter);
        }
        }).start();
        new Thread(new Runnable() {
        public void run() {
        // Sleep for a bit so that thread 1 has a chance to start
        try {
        Thread.sleep(100);
        } catch (InterruptedException ignored) {
        // catch block
        }
        System.out.println("Thread 2 finishing");
        running = false;
        }
        }).start();
        }

        public static void main(String args) {
        new ThreadTest().test();
        }
        }





        share|improve this answer























        • Sorry, I tried to remove "volatile" keyword and run the program for many times, but every time thread 1 can be terminated. I think for the code you provided even without "volatile" thread 1 can always be terminated every time.
          – Eric Jiang
          Apr 28 '11 at 10:40






        • 3




          @Eric: it gives the effect I describe on two different machines running Java 6 JVMs. I guess I should have phrased it differently. It is only guaranteed to terminate if the volatile keyword is present. If it's not present, the JVM is free to cache the value of running, so thread 1 need not terminate. However, it isn't forced to cache the value.
          – Simon Nickerson
          Apr 28 '11 at 11:25










        • Keeping "volatile" present will terminate thread 1 as soon as 'running' is set false in thread 2. But if remove "volatile", thread 1 may won't terminate even after 'running' is set false in thread2, when thread will terminate depends on when JVM update "running" value in thread 1. Do you mean that??? But if "running" has been set 'false' in thread 2, why thread1 can't get the right value??? If so I think JVM behave wrong.
          – Eric Jiang
          Apr 28 '11 at 11:53






        • 1




          The JVM is not behaving wrongly. Without volatile (or synchronization, or something else which forces a 'happens-before' relationship), thread 1 need not see the change made by thread 2.
          – Simon Nickerson
          Apr 28 '11 at 12:02






        • 2




          @Eric: that's exactly the problem: "correct behaviour" is not equivalent to "intuitive behaviour". JVMs are free to cache values (for example in the register of a CPU) if it is read repeatedly and need not read it from main memory each time. Specifying that a variable is volatile disables this caching!
          – Joachim Sauer
          Apr 28 '11 at 14:41















        up vote
        13
        down vote



        accepted










        Here is an example of why volatile is necessary. If you remove the keyword volatile, thread 1 may never terminate. (When I tested on Java 1.6 Hotspot on Linux, this was indeed the case - your results may vary as the JVM is not obliged to do any caching of variables not marked volatile.)



        public class ThreadTest {
        volatile boolean running = true;

        public void test() {
        new Thread(new Runnable() {
        public void run() {
        int counter = 0;
        while (running) {
        counter++;
        }
        System.out.println("Thread 1 finished. Counted up to " + counter);
        }
        }).start();
        new Thread(new Runnable() {
        public void run() {
        // Sleep for a bit so that thread 1 has a chance to start
        try {
        Thread.sleep(100);
        } catch (InterruptedException ignored) {
        // catch block
        }
        System.out.println("Thread 2 finishing");
        running = false;
        }
        }).start();
        }

        public static void main(String args) {
        new ThreadTest().test();
        }
        }





        share|improve this answer























        • Sorry, I tried to remove "volatile" keyword and run the program for many times, but every time thread 1 can be terminated. I think for the code you provided even without "volatile" thread 1 can always be terminated every time.
          – Eric Jiang
          Apr 28 '11 at 10:40






        • 3




          @Eric: it gives the effect I describe on two different machines running Java 6 JVMs. I guess I should have phrased it differently. It is only guaranteed to terminate if the volatile keyword is present. If it's not present, the JVM is free to cache the value of running, so thread 1 need not terminate. However, it isn't forced to cache the value.
          – Simon Nickerson
          Apr 28 '11 at 11:25










        • Keeping "volatile" present will terminate thread 1 as soon as 'running' is set false in thread 2. But if remove "volatile", thread 1 may won't terminate even after 'running' is set false in thread2, when thread will terminate depends on when JVM update "running" value in thread 1. Do you mean that??? But if "running" has been set 'false' in thread 2, why thread1 can't get the right value??? If so I think JVM behave wrong.
          – Eric Jiang
          Apr 28 '11 at 11:53






        • 1




          The JVM is not behaving wrongly. Without volatile (or synchronization, or something else which forces a 'happens-before' relationship), thread 1 need not see the change made by thread 2.
          – Simon Nickerson
          Apr 28 '11 at 12:02






        • 2




          @Eric: that's exactly the problem: "correct behaviour" is not equivalent to "intuitive behaviour". JVMs are free to cache values (for example in the register of a CPU) if it is read repeatedly and need not read it from main memory each time. Specifying that a variable is volatile disables this caching!
          – Joachim Sauer
          Apr 28 '11 at 14:41













        up vote
        13
        down vote



        accepted







        up vote
        13
        down vote



        accepted






        Here is an example of why volatile is necessary. If you remove the keyword volatile, thread 1 may never terminate. (When I tested on Java 1.6 Hotspot on Linux, this was indeed the case - your results may vary as the JVM is not obliged to do any caching of variables not marked volatile.)



        public class ThreadTest {
        volatile boolean running = true;

        public void test() {
        new Thread(new Runnable() {
        public void run() {
        int counter = 0;
        while (running) {
        counter++;
        }
        System.out.println("Thread 1 finished. Counted up to " + counter);
        }
        }).start();
        new Thread(new Runnable() {
        public void run() {
        // Sleep for a bit so that thread 1 has a chance to start
        try {
        Thread.sleep(100);
        } catch (InterruptedException ignored) {
        // catch block
        }
        System.out.println("Thread 2 finishing");
        running = false;
        }
        }).start();
        }

        public static void main(String args) {
        new ThreadTest().test();
        }
        }





        share|improve this answer














        Here is an example of why volatile is necessary. If you remove the keyword volatile, thread 1 may never terminate. (When I tested on Java 1.6 Hotspot on Linux, this was indeed the case - your results may vary as the JVM is not obliged to do any caching of variables not marked volatile.)



        public class ThreadTest {
        volatile boolean running = true;

        public void test() {
        new Thread(new Runnable() {
        public void run() {
        int counter = 0;
        while (running) {
        counter++;
        }
        System.out.println("Thread 1 finished. Counted up to " + counter);
        }
        }).start();
        new Thread(new Runnable() {
        public void run() {
        // Sleep for a bit so that thread 1 has a chance to start
        try {
        Thread.sleep(100);
        } catch (InterruptedException ignored) {
        // catch block
        }
        System.out.println("Thread 2 finishing");
        running = false;
        }
        }).start();
        }

        public static void main(String args) {
        new ThreadTest().test();
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 10 at 2:58









        vikiiii

        6,72193964




        6,72193964










        answered Apr 28 '11 at 10:12









        Simon Nickerson

        30.1k1687122




        30.1k1687122












        • Sorry, I tried to remove "volatile" keyword and run the program for many times, but every time thread 1 can be terminated. I think for the code you provided even without "volatile" thread 1 can always be terminated every time.
          – Eric Jiang
          Apr 28 '11 at 10:40






        • 3




          @Eric: it gives the effect I describe on two different machines running Java 6 JVMs. I guess I should have phrased it differently. It is only guaranteed to terminate if the volatile keyword is present. If it's not present, the JVM is free to cache the value of running, so thread 1 need not terminate. However, it isn't forced to cache the value.
          – Simon Nickerson
          Apr 28 '11 at 11:25










        • Keeping "volatile" present will terminate thread 1 as soon as 'running' is set false in thread 2. But if remove "volatile", thread 1 may won't terminate even after 'running' is set false in thread2, when thread will terminate depends on when JVM update "running" value in thread 1. Do you mean that??? But if "running" has been set 'false' in thread 2, why thread1 can't get the right value??? If so I think JVM behave wrong.
          – Eric Jiang
          Apr 28 '11 at 11:53






        • 1




          The JVM is not behaving wrongly. Without volatile (or synchronization, or something else which forces a 'happens-before' relationship), thread 1 need not see the change made by thread 2.
          – Simon Nickerson
          Apr 28 '11 at 12:02






        • 2




          @Eric: that's exactly the problem: "correct behaviour" is not equivalent to "intuitive behaviour". JVMs are free to cache values (for example in the register of a CPU) if it is read repeatedly and need not read it from main memory each time. Specifying that a variable is volatile disables this caching!
          – Joachim Sauer
          Apr 28 '11 at 14:41


















        • Sorry, I tried to remove "volatile" keyword and run the program for many times, but every time thread 1 can be terminated. I think for the code you provided even without "volatile" thread 1 can always be terminated every time.
          – Eric Jiang
          Apr 28 '11 at 10:40






        • 3




          @Eric: it gives the effect I describe on two different machines running Java 6 JVMs. I guess I should have phrased it differently. It is only guaranteed to terminate if the volatile keyword is present. If it's not present, the JVM is free to cache the value of running, so thread 1 need not terminate. However, it isn't forced to cache the value.
          – Simon Nickerson
          Apr 28 '11 at 11:25










        • Keeping "volatile" present will terminate thread 1 as soon as 'running' is set false in thread 2. But if remove "volatile", thread 1 may won't terminate even after 'running' is set false in thread2, when thread will terminate depends on when JVM update "running" value in thread 1. Do you mean that??? But if "running" has been set 'false' in thread 2, why thread1 can't get the right value??? If so I think JVM behave wrong.
          – Eric Jiang
          Apr 28 '11 at 11:53






        • 1




          The JVM is not behaving wrongly. Without volatile (or synchronization, or something else which forces a 'happens-before' relationship), thread 1 need not see the change made by thread 2.
          – Simon Nickerson
          Apr 28 '11 at 12:02






        • 2




          @Eric: that's exactly the problem: "correct behaviour" is not equivalent to "intuitive behaviour". JVMs are free to cache values (for example in the register of a CPU) if it is read repeatedly and need not read it from main memory each time. Specifying that a variable is volatile disables this caching!
          – Joachim Sauer
          Apr 28 '11 at 14:41
















        Sorry, I tried to remove "volatile" keyword and run the program for many times, but every time thread 1 can be terminated. I think for the code you provided even without "volatile" thread 1 can always be terminated every time.
        – Eric Jiang
        Apr 28 '11 at 10:40




        Sorry, I tried to remove "volatile" keyword and run the program for many times, but every time thread 1 can be terminated. I think for the code you provided even without "volatile" thread 1 can always be terminated every time.
        – Eric Jiang
        Apr 28 '11 at 10:40




        3




        3




        @Eric: it gives the effect I describe on two different machines running Java 6 JVMs. I guess I should have phrased it differently. It is only guaranteed to terminate if the volatile keyword is present. If it's not present, the JVM is free to cache the value of running, so thread 1 need not terminate. However, it isn't forced to cache the value.
        – Simon Nickerson
        Apr 28 '11 at 11:25




        @Eric: it gives the effect I describe on two different machines running Java 6 JVMs. I guess I should have phrased it differently. It is only guaranteed to terminate if the volatile keyword is present. If it's not present, the JVM is free to cache the value of running, so thread 1 need not terminate. However, it isn't forced to cache the value.
        – Simon Nickerson
        Apr 28 '11 at 11:25












        Keeping "volatile" present will terminate thread 1 as soon as 'running' is set false in thread 2. But if remove "volatile", thread 1 may won't terminate even after 'running' is set false in thread2, when thread will terminate depends on when JVM update "running" value in thread 1. Do you mean that??? But if "running" has been set 'false' in thread 2, why thread1 can't get the right value??? If so I think JVM behave wrong.
        – Eric Jiang
        Apr 28 '11 at 11:53




        Keeping "volatile" present will terminate thread 1 as soon as 'running' is set false in thread 2. But if remove "volatile", thread 1 may won't terminate even after 'running' is set false in thread2, when thread will terminate depends on when JVM update "running" value in thread 1. Do you mean that??? But if "running" has been set 'false' in thread 2, why thread1 can't get the right value??? If so I think JVM behave wrong.
        – Eric Jiang
        Apr 28 '11 at 11:53




        1




        1




        The JVM is not behaving wrongly. Without volatile (or synchronization, or something else which forces a 'happens-before' relationship), thread 1 need not see the change made by thread 2.
        – Simon Nickerson
        Apr 28 '11 at 12:02




        The JVM is not behaving wrongly. Without volatile (or synchronization, or something else which forces a 'happens-before' relationship), thread 1 need not see the change made by thread 2.
        – Simon Nickerson
        Apr 28 '11 at 12:02




        2




        2




        @Eric: that's exactly the problem: "correct behaviour" is not equivalent to "intuitive behaviour". JVMs are free to cache values (for example in the register of a CPU) if it is read repeatedly and need not read it from main memory each time. Specifying that a variable is volatile disables this caching!
        – Joachim Sauer
        Apr 28 '11 at 14:41




        @Eric: that's exactly the problem: "correct behaviour" is not equivalent to "intuitive behaviour". JVMs are free to cache values (for example in the register of a CPU) if it is read repeatedly and need not read it from main memory each time. Specifying that a variable is volatile disables this caching!
        – Joachim Sauer
        Apr 28 '11 at 14:41












        up vote
        4
        down vote













        The following is a canonical example of the necessity of volatile (in this case for the str variable. Without it, hotspot lifts the access outside the loop (while (str == null)) and run() never terminates. This will happen on most -server JVMs.



        public class DelayWrite implements Runnable {
        private String str;
        void setStr(String str) {this.str = str;}

        public void run() {
          while (str == null);
          System.out.println(str);
        }

        public static void main(String args) {
          DelayWrite delay = new DelayWrite();
          new Thread(delay).start();
          Thread.sleep(1000);
          delay.setStr("Hello world!!");
        }
        }





        share|improve this answer























        • Wesley: Thank you very much!!! I can see the issue with java -server to start JVM and run the app. Now I get my answer, thanks!
          – Eric Jiang
          Apr 29 '11 at 3:20










        • new Thread(fun).start(); this line should be new Thread(delay).start(); correct ?
          – Dhanaraj Durairaj
          Feb 4 '15 at 9:00










        • yes, fixed. thx.
          – Jed Wesley-Smith
          Feb 4 '15 at 23:26










        • Great and useful! I have another questions, 1) Why you use 'canonical '? 2) How could I get the assembly code when the java code is running? can I get some clue from assembly, like other cpp code demonstrations?
          – gfan
          Mar 18 '17 at 11:09















        up vote
        4
        down vote













        The following is a canonical example of the necessity of volatile (in this case for the str variable. Without it, hotspot lifts the access outside the loop (while (str == null)) and run() never terminates. This will happen on most -server JVMs.



        public class DelayWrite implements Runnable {
        private String str;
        void setStr(String str) {this.str = str;}

        public void run() {
          while (str == null);
          System.out.println(str);
        }

        public static void main(String args) {
          DelayWrite delay = new DelayWrite();
          new Thread(delay).start();
          Thread.sleep(1000);
          delay.setStr("Hello world!!");
        }
        }





        share|improve this answer























        • Wesley: Thank you very much!!! I can see the issue with java -server to start JVM and run the app. Now I get my answer, thanks!
          – Eric Jiang
          Apr 29 '11 at 3:20










        • new Thread(fun).start(); this line should be new Thread(delay).start(); correct ?
          – Dhanaraj Durairaj
          Feb 4 '15 at 9:00










        • yes, fixed. thx.
          – Jed Wesley-Smith
          Feb 4 '15 at 23:26










        • Great and useful! I have another questions, 1) Why you use 'canonical '? 2) How could I get the assembly code when the java code is running? can I get some clue from assembly, like other cpp code demonstrations?
          – gfan
          Mar 18 '17 at 11:09













        up vote
        4
        down vote










        up vote
        4
        down vote









        The following is a canonical example of the necessity of volatile (in this case for the str variable. Without it, hotspot lifts the access outside the loop (while (str == null)) and run() never terminates. This will happen on most -server JVMs.



        public class DelayWrite implements Runnable {
        private String str;
        void setStr(String str) {this.str = str;}

        public void run() {
          while (str == null);
          System.out.println(str);
        }

        public static void main(String args) {
          DelayWrite delay = new DelayWrite();
          new Thread(delay).start();
          Thread.sleep(1000);
          delay.setStr("Hello world!!");
        }
        }





        share|improve this answer














        The following is a canonical example of the necessity of volatile (in this case for the str variable. Without it, hotspot lifts the access outside the loop (while (str == null)) and run() never terminates. This will happen on most -server JVMs.



        public class DelayWrite implements Runnable {
        private String str;
        void setStr(String str) {this.str = str;}

        public void run() {
          while (str == null);
          System.out.println(str);
        }

        public static void main(String args) {
          DelayWrite delay = new DelayWrite();
          new Thread(delay).start();
          Thread.sleep(1000);
          delay.setStr("Hello world!!");
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 4 '15 at 23:26

























        answered Apr 28 '11 at 22:31









        Jed Wesley-Smith

        4,1661319




        4,1661319












        • Wesley: Thank you very much!!! I can see the issue with java -server to start JVM and run the app. Now I get my answer, thanks!
          – Eric Jiang
          Apr 29 '11 at 3:20










        • new Thread(fun).start(); this line should be new Thread(delay).start(); correct ?
          – Dhanaraj Durairaj
          Feb 4 '15 at 9:00










        • yes, fixed. thx.
          – Jed Wesley-Smith
          Feb 4 '15 at 23:26










        • Great and useful! I have another questions, 1) Why you use 'canonical '? 2) How could I get the assembly code when the java code is running? can I get some clue from assembly, like other cpp code demonstrations?
          – gfan
          Mar 18 '17 at 11:09


















        • Wesley: Thank you very much!!! I can see the issue with java -server to start JVM and run the app. Now I get my answer, thanks!
          – Eric Jiang
          Apr 29 '11 at 3:20










        • new Thread(fun).start(); this line should be new Thread(delay).start(); correct ?
          – Dhanaraj Durairaj
          Feb 4 '15 at 9:00










        • yes, fixed. thx.
          – Jed Wesley-Smith
          Feb 4 '15 at 23:26










        • Great and useful! I have another questions, 1) Why you use 'canonical '? 2) How could I get the assembly code when the java code is running? can I get some clue from assembly, like other cpp code demonstrations?
          – gfan
          Mar 18 '17 at 11:09
















        Wesley: Thank you very much!!! I can see the issue with java -server to start JVM and run the app. Now I get my answer, thanks!
        – Eric Jiang
        Apr 29 '11 at 3:20




        Wesley: Thank you very much!!! I can see the issue with java -server to start JVM and run the app. Now I get my answer, thanks!
        – Eric Jiang
        Apr 29 '11 at 3:20












        new Thread(fun).start(); this line should be new Thread(delay).start(); correct ?
        – Dhanaraj Durairaj
        Feb 4 '15 at 9:00




        new Thread(fun).start(); this line should be new Thread(delay).start(); correct ?
        – Dhanaraj Durairaj
        Feb 4 '15 at 9:00












        yes, fixed. thx.
        – Jed Wesley-Smith
        Feb 4 '15 at 23:26




        yes, fixed. thx.
        – Jed Wesley-Smith
        Feb 4 '15 at 23:26












        Great and useful! I have another questions, 1) Why you use 'canonical '? 2) How could I get the assembly code when the java code is running? can I get some clue from assembly, like other cpp code demonstrations?
        – gfan
        Mar 18 '17 at 11:09




        Great and useful! I have another questions, 1) Why you use 'canonical '? 2) How could I get the assembly code when the java code is running? can I get some clue from assembly, like other cpp code demonstrations?
        – gfan
        Mar 18 '17 at 11:09










        up vote
        2
        down vote













        Eric, I have read your comments and one in particular strikes me




        In fact, I can understand the usage of volatile on the concept
        level. But for practice, I can't think
        up the code which has concurrency
        problems without using volatile




        The obvious problem you can have are compiler reorderings, for example the more famous hoisting as mentioned by Simon Nickerson. But let's assume that there will be no reorderings, that comment can be a valid one.



        Another issue that volatile resolves are with 64 bit variables (long, double). If you write to a long or a double, it is treated as two separate 32 bit stores. What can happen with a concurrent write is the high 32 of one thread gets written to high 32 bits of the register while another thread writes the low 32 bit. You can then have a long that is neither one or the other.



        Also, if you look at the memory section of the JLS you will observe it to be a relaxed memory model.



        That means writes may not become visible (can be sitting in a store buffer) for a while. This can lead to stale reads. Now you may say that seems unlikely, and it is, but your program is incorrect and has potential to fail.



        If you have an int that you are incrementing for the lifetime of an application and you know (or at least think) the int wont overflow then you don't upgrade it to a long, but it is still possible it can. In the case of a memory visibility issue, if you think it shouldn't effect you, you should know that it still can and can cause errors in your concurrent application that are extremely difficult to identify. Correctness is the reason to use volatile.






        share|improve this answer

























          up vote
          2
          down vote













          Eric, I have read your comments and one in particular strikes me




          In fact, I can understand the usage of volatile on the concept
          level. But for practice, I can't think
          up the code which has concurrency
          problems without using volatile




          The obvious problem you can have are compiler reorderings, for example the more famous hoisting as mentioned by Simon Nickerson. But let's assume that there will be no reorderings, that comment can be a valid one.



          Another issue that volatile resolves are with 64 bit variables (long, double). If you write to a long or a double, it is treated as two separate 32 bit stores. What can happen with a concurrent write is the high 32 of one thread gets written to high 32 bits of the register while another thread writes the low 32 bit. You can then have a long that is neither one or the other.



          Also, if you look at the memory section of the JLS you will observe it to be a relaxed memory model.



          That means writes may not become visible (can be sitting in a store buffer) for a while. This can lead to stale reads. Now you may say that seems unlikely, and it is, but your program is incorrect and has potential to fail.



          If you have an int that you are incrementing for the lifetime of an application and you know (or at least think) the int wont overflow then you don't upgrade it to a long, but it is still possible it can. In the case of a memory visibility issue, if you think it shouldn't effect you, you should know that it still can and can cause errors in your concurrent application that are extremely difficult to identify. Correctness is the reason to use volatile.






          share|improve this answer























            up vote
            2
            down vote










            up vote
            2
            down vote









            Eric, I have read your comments and one in particular strikes me




            In fact, I can understand the usage of volatile on the concept
            level. But for practice, I can't think
            up the code which has concurrency
            problems without using volatile




            The obvious problem you can have are compiler reorderings, for example the more famous hoisting as mentioned by Simon Nickerson. But let's assume that there will be no reorderings, that comment can be a valid one.



            Another issue that volatile resolves are with 64 bit variables (long, double). If you write to a long or a double, it is treated as two separate 32 bit stores. What can happen with a concurrent write is the high 32 of one thread gets written to high 32 bits of the register while another thread writes the low 32 bit. You can then have a long that is neither one or the other.



            Also, if you look at the memory section of the JLS you will observe it to be a relaxed memory model.



            That means writes may not become visible (can be sitting in a store buffer) for a while. This can lead to stale reads. Now you may say that seems unlikely, and it is, but your program is incorrect and has potential to fail.



            If you have an int that you are incrementing for the lifetime of an application and you know (or at least think) the int wont overflow then you don't upgrade it to a long, but it is still possible it can. In the case of a memory visibility issue, if you think it shouldn't effect you, you should know that it still can and can cause errors in your concurrent application that are extremely difficult to identify. Correctness is the reason to use volatile.






            share|improve this answer












            Eric, I have read your comments and one in particular strikes me




            In fact, I can understand the usage of volatile on the concept
            level. But for practice, I can't think
            up the code which has concurrency
            problems without using volatile




            The obvious problem you can have are compiler reorderings, for example the more famous hoisting as mentioned by Simon Nickerson. But let's assume that there will be no reorderings, that comment can be a valid one.



            Another issue that volatile resolves are with 64 bit variables (long, double). If you write to a long or a double, it is treated as two separate 32 bit stores. What can happen with a concurrent write is the high 32 of one thread gets written to high 32 bits of the register while another thread writes the low 32 bit. You can then have a long that is neither one or the other.



            Also, if you look at the memory section of the JLS you will observe it to be a relaxed memory model.



            That means writes may not become visible (can be sitting in a store buffer) for a while. This can lead to stale reads. Now you may say that seems unlikely, and it is, but your program is incorrect and has potential to fail.



            If you have an int that you are incrementing for the lifetime of an application and you know (or at least think) the int wont overflow then you don't upgrade it to a long, but it is still possible it can. In the case of a memory visibility issue, if you think it shouldn't effect you, you should know that it still can and can cause errors in your concurrent application that are extremely difficult to identify. Correctness is the reason to use volatile.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Apr 28 '11 at 14:28









            John Vint

            33k55990




            33k55990






















                up vote
                1
                down vote













                The volatile keyword is pretty complex and you need to understand what it does and does not do well before you use it. I recommend reading this language specification section which explains it very well.



                They highlight this example:



                class Test {
                static volatile int i = 0, j = 0;
                static void one() { i++; j++; }
                static void two() {
                System.out.println("i=" + i + " j=" + j);
                }
                }


                What this means is that during one() j is never greater than i. However, another Thread running two() might print out a value of j that is much larger than i because let's say two() is running and fetches the value of i. Then one() runs 1000 times. Then the Thread running two finally gets scheduled again and picks up j which is now much larger than the value of i. I think this example perfectly demonstrates the difference between volatile and synchronized - the updates to i and j are volatile which means that the order that they happen in is consistent with the source code. However the two updates happen separately and not atomically so callers may see values that look (to that caller) to be inconsistent.



                In a nutshell: Be very careful with volatile!






                share|improve this answer























                • From the link you provide, an example below: class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } "This allows method one and method two to be executed concurrently, but guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread" But I don't think the example is correct, using "volatile' or not has same result, j always has the chance to be different from i.
                  – Eric Jiang
                  Apr 28 '11 at 10:50












                • @Eric Jiang - The point is j can be greater than i. Although i is always incremented first. If both are volatile, they can still be different, but j can not be greater than i.
                  – Ishtar
                  Apr 28 '11 at 11:43










                • I've updated my answer to explain what i think the JLS is saying (although i think the JLS said it very well in the first place) :)
                  – alpian
                  Apr 28 '11 at 12:00










                • Thanks alpian, in fact, I can catch your meaning very well, but when I run the code and test for many many times I never see J is greater than i. Is it related to my PC environment, such as JDK version or hardware? Can I understand as that even the code is running for hundreds thousands of times there may be one time that J is greater than i (just has risk but maybe won't happen, so need to use 'volatile' to guarantee), right?
                  – Eric Jiang
                  Apr 29 '11 at 2:48















                up vote
                1
                down vote













                The volatile keyword is pretty complex and you need to understand what it does and does not do well before you use it. I recommend reading this language specification section which explains it very well.



                They highlight this example:



                class Test {
                static volatile int i = 0, j = 0;
                static void one() { i++; j++; }
                static void two() {
                System.out.println("i=" + i + " j=" + j);
                }
                }


                What this means is that during one() j is never greater than i. However, another Thread running two() might print out a value of j that is much larger than i because let's say two() is running and fetches the value of i. Then one() runs 1000 times. Then the Thread running two finally gets scheduled again and picks up j which is now much larger than the value of i. I think this example perfectly demonstrates the difference between volatile and synchronized - the updates to i and j are volatile which means that the order that they happen in is consistent with the source code. However the two updates happen separately and not atomically so callers may see values that look (to that caller) to be inconsistent.



                In a nutshell: Be very careful with volatile!






                share|improve this answer























                • From the link you provide, an example below: class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } "This allows method one and method two to be executed concurrently, but guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread" But I don't think the example is correct, using "volatile' or not has same result, j always has the chance to be different from i.
                  – Eric Jiang
                  Apr 28 '11 at 10:50












                • @Eric Jiang - The point is j can be greater than i. Although i is always incremented first. If both are volatile, they can still be different, but j can not be greater than i.
                  – Ishtar
                  Apr 28 '11 at 11:43










                • I've updated my answer to explain what i think the JLS is saying (although i think the JLS said it very well in the first place) :)
                  – alpian
                  Apr 28 '11 at 12:00










                • Thanks alpian, in fact, I can catch your meaning very well, but when I run the code and test for many many times I never see J is greater than i. Is it related to my PC environment, such as JDK version or hardware? Can I understand as that even the code is running for hundreds thousands of times there may be one time that J is greater than i (just has risk but maybe won't happen, so need to use 'volatile' to guarantee), right?
                  – Eric Jiang
                  Apr 29 '11 at 2:48













                up vote
                1
                down vote










                up vote
                1
                down vote









                The volatile keyword is pretty complex and you need to understand what it does and does not do well before you use it. I recommend reading this language specification section which explains it very well.



                They highlight this example:



                class Test {
                static volatile int i = 0, j = 0;
                static void one() { i++; j++; }
                static void two() {
                System.out.println("i=" + i + " j=" + j);
                }
                }


                What this means is that during one() j is never greater than i. However, another Thread running two() might print out a value of j that is much larger than i because let's say two() is running and fetches the value of i. Then one() runs 1000 times. Then the Thread running two finally gets scheduled again and picks up j which is now much larger than the value of i. I think this example perfectly demonstrates the difference between volatile and synchronized - the updates to i and j are volatile which means that the order that they happen in is consistent with the source code. However the two updates happen separately and not atomically so callers may see values that look (to that caller) to be inconsistent.



                In a nutshell: Be very careful with volatile!






                share|improve this answer














                The volatile keyword is pretty complex and you need to understand what it does and does not do well before you use it. I recommend reading this language specification section which explains it very well.



                They highlight this example:



                class Test {
                static volatile int i = 0, j = 0;
                static void one() { i++; j++; }
                static void two() {
                System.out.println("i=" + i + " j=" + j);
                }
                }


                What this means is that during one() j is never greater than i. However, another Thread running two() might print out a value of j that is much larger than i because let's say two() is running and fetches the value of i. Then one() runs 1000 times. Then the Thread running two finally gets scheduled again and picks up j which is now much larger than the value of i. I think this example perfectly demonstrates the difference between volatile and synchronized - the updates to i and j are volatile which means that the order that they happen in is consistent with the source code. However the two updates happen separately and not atomically so callers may see values that look (to that caller) to be inconsistent.



                In a nutshell: Be very careful with volatile!







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Apr 28 '11 at 11:58

























                answered Apr 28 '11 at 10:06









                alpian

                4,0501418




                4,0501418












                • From the link you provide, an example below: class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } "This allows method one and method two to be executed concurrently, but guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread" But I don't think the example is correct, using "volatile' or not has same result, j always has the chance to be different from i.
                  – Eric Jiang
                  Apr 28 '11 at 10:50












                • @Eric Jiang - The point is j can be greater than i. Although i is always incremented first. If both are volatile, they can still be different, but j can not be greater than i.
                  – Ishtar
                  Apr 28 '11 at 11:43










                • I've updated my answer to explain what i think the JLS is saying (although i think the JLS said it very well in the first place) :)
                  – alpian
                  Apr 28 '11 at 12:00










                • Thanks alpian, in fact, I can catch your meaning very well, but when I run the code and test for many many times I never see J is greater than i. Is it related to my PC environment, such as JDK version or hardware? Can I understand as that even the code is running for hundreds thousands of times there may be one time that J is greater than i (just has risk but maybe won't happen, so need to use 'volatile' to guarantee), right?
                  – Eric Jiang
                  Apr 29 '11 at 2:48


















                • From the link you provide, an example below: class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } "This allows method one and method two to be executed concurrently, but guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread" But I don't think the example is correct, using "volatile' or not has same result, j always has the chance to be different from i.
                  – Eric Jiang
                  Apr 28 '11 at 10:50












                • @Eric Jiang - The point is j can be greater than i. Although i is always incremented first. If both are volatile, they can still be different, but j can not be greater than i.
                  – Ishtar
                  Apr 28 '11 at 11:43










                • I've updated my answer to explain what i think the JLS is saying (although i think the JLS said it very well in the first place) :)
                  – alpian
                  Apr 28 '11 at 12:00










                • Thanks alpian, in fact, I can catch your meaning very well, but when I run the code and test for many many times I never see J is greater than i. Is it related to my PC environment, such as JDK version or hardware? Can I understand as that even the code is running for hundreds thousands of times there may be one time that J is greater than i (just has risk but maybe won't happen, so need to use 'volatile' to guarantee), right?
                  – Eric Jiang
                  Apr 29 '11 at 2:48
















                From the link you provide, an example below: class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } "This allows method one and method two to be executed concurrently, but guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread" But I don't think the example is correct, using "volatile' or not has same result, j always has the chance to be different from i.
                – Eric Jiang
                Apr 28 '11 at 10:50






                From the link you provide, an example below: class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } "This allows method one and method two to be executed concurrently, but guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread" But I don't think the example is correct, using "volatile' or not has same result, j always has the chance to be different from i.
                – Eric Jiang
                Apr 28 '11 at 10:50














                @Eric Jiang - The point is j can be greater than i. Although i is always incremented first. If both are volatile, they can still be different, but j can not be greater than i.
                – Ishtar
                Apr 28 '11 at 11:43




                @Eric Jiang - The point is j can be greater than i. Although i is always incremented first. If both are volatile, they can still be different, but j can not be greater than i.
                – Ishtar
                Apr 28 '11 at 11:43












                I've updated my answer to explain what i think the JLS is saying (although i think the JLS said it very well in the first place) :)
                – alpian
                Apr 28 '11 at 12:00




                I've updated my answer to explain what i think the JLS is saying (although i think the JLS said it very well in the first place) :)
                – alpian
                Apr 28 '11 at 12:00












                Thanks alpian, in fact, I can catch your meaning very well, but when I run the code and test for many many times I never see J is greater than i. Is it related to my PC environment, such as JDK version or hardware? Can I understand as that even the code is running for hundreds thousands of times there may be one time that J is greater than i (just has risk but maybe won't happen, so need to use 'volatile' to guarantee), right?
                – Eric Jiang
                Apr 29 '11 at 2:48




                Thanks alpian, in fact, I can catch your meaning very well, but when I run the code and test for many many times I never see J is greater than i. Is it related to my PC environment, such as JDK version or hardware? Can I understand as that even the code is running for hundreds thousands of times there may be one time that J is greater than i (just has risk but maybe won't happen, so need to use 'volatile' to guarantee), right?
                – Eric Jiang
                Apr 29 '11 at 2:48










                up vote
                0
                down vote













                A minimalist example in java 8, if you remove volatile keyword it will never end.



                public class VolatileExample {

                private static volatile boolean BOOL = true;

                public static void main(String args) throws InterruptedException {
                new Thread(() -> { while (BOOL) { } }).start();
                TimeUnit.MILLISECONDS.sleep(500);
                BOOL = false;
                }
                }





                share|improve this answer

























                  up vote
                  0
                  down vote













                  A minimalist example in java 8, if you remove volatile keyword it will never end.



                  public class VolatileExample {

                  private static volatile boolean BOOL = true;

                  public static void main(String args) throws InterruptedException {
                  new Thread(() -> { while (BOOL) { } }).start();
                  TimeUnit.MILLISECONDS.sleep(500);
                  BOOL = false;
                  }
                  }





                  share|improve this answer























                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    A minimalist example in java 8, if you remove volatile keyword it will never end.



                    public class VolatileExample {

                    private static volatile boolean BOOL = true;

                    public static void main(String args) throws InterruptedException {
                    new Thread(() -> { while (BOOL) { } }).start();
                    TimeUnit.MILLISECONDS.sleep(500);
                    BOOL = false;
                    }
                    }





                    share|improve this answer












                    A minimalist example in java 8, if you remove volatile keyword it will never end.



                    public class VolatileExample {

                    private static volatile boolean BOOL = true;

                    public static void main(String args) throws InterruptedException {
                    new Thread(() -> { while (BOOL) { } }).start();
                    TimeUnit.MILLISECONDS.sleep(500);
                    BOOL = false;
                    }
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Oct 30 '17 at 23:39









                    Arnaud

                    11




                    11






















                        up vote
                        0
                        down vote













                        To expand on the answer from @jed-wesley-smith, if you drop this into a new project, take out the volatile keyword from the iterationCount, and run it, it will never stop. Adding the volatile keyword to either str or iterationCount would cause the code to end successfully. I've also noticed that the sleep can't be smaller than 5, using Java 8, but perhaps your mileage may vary with other JVMs / Java versions.



                        public static class DelayWrite implements Runnable
                        {
                        private String str;
                        public volatile int iterationCount = 0;

                        void setStr(String str)
                        {
                        this.str = str;
                        }

                        public void run()
                        {
                        while (str == null)
                        {
                        iterationCount++;
                        }
                        System.out.println(str + " after " + iterationCount + " iterations.");
                        }
                        }

                        public static void main(String args) throws InterruptedException
                        {
                        System.out.println("This should print 'Hello world!' and exit if str or iterationCount is volatile.");
                        DelayWrite delay = new DelayWrite();
                        new Thread(delay).start();
                        Thread.sleep(5);
                        System.out.println("Thread sleep gave the thread " + delay.iterationCount + " iterations.");
                        delay.setStr("Hello world!!");
                        }





                        share|improve this answer

























                          up vote
                          0
                          down vote













                          To expand on the answer from @jed-wesley-smith, if you drop this into a new project, take out the volatile keyword from the iterationCount, and run it, it will never stop. Adding the volatile keyword to either str or iterationCount would cause the code to end successfully. I've also noticed that the sleep can't be smaller than 5, using Java 8, but perhaps your mileage may vary with other JVMs / Java versions.



                          public static class DelayWrite implements Runnable
                          {
                          private String str;
                          public volatile int iterationCount = 0;

                          void setStr(String str)
                          {
                          this.str = str;
                          }

                          public void run()
                          {
                          while (str == null)
                          {
                          iterationCount++;
                          }
                          System.out.println(str + " after " + iterationCount + " iterations.");
                          }
                          }

                          public static void main(String args) throws InterruptedException
                          {
                          System.out.println("This should print 'Hello world!' and exit if str or iterationCount is volatile.");
                          DelayWrite delay = new DelayWrite();
                          new Thread(delay).start();
                          Thread.sleep(5);
                          System.out.println("Thread sleep gave the thread " + delay.iterationCount + " iterations.");
                          delay.setStr("Hello world!!");
                          }





                          share|improve this answer























                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            To expand on the answer from @jed-wesley-smith, if you drop this into a new project, take out the volatile keyword from the iterationCount, and run it, it will never stop. Adding the volatile keyword to either str or iterationCount would cause the code to end successfully. I've also noticed that the sleep can't be smaller than 5, using Java 8, but perhaps your mileage may vary with other JVMs / Java versions.



                            public static class DelayWrite implements Runnable
                            {
                            private String str;
                            public volatile int iterationCount = 0;

                            void setStr(String str)
                            {
                            this.str = str;
                            }

                            public void run()
                            {
                            while (str == null)
                            {
                            iterationCount++;
                            }
                            System.out.println(str + " after " + iterationCount + " iterations.");
                            }
                            }

                            public static void main(String args) throws InterruptedException
                            {
                            System.out.println("This should print 'Hello world!' and exit if str or iterationCount is volatile.");
                            DelayWrite delay = new DelayWrite();
                            new Thread(delay).start();
                            Thread.sleep(5);
                            System.out.println("Thread sleep gave the thread " + delay.iterationCount + " iterations.");
                            delay.setStr("Hello world!!");
                            }





                            share|improve this answer












                            To expand on the answer from @jed-wesley-smith, if you drop this into a new project, take out the volatile keyword from the iterationCount, and run it, it will never stop. Adding the volatile keyword to either str or iterationCount would cause the code to end successfully. I've also noticed that the sleep can't be smaller than 5, using Java 8, but perhaps your mileage may vary with other JVMs / Java versions.



                            public static class DelayWrite implements Runnable
                            {
                            private String str;
                            public volatile int iterationCount = 0;

                            void setStr(String str)
                            {
                            this.str = str;
                            }

                            public void run()
                            {
                            while (str == null)
                            {
                            iterationCount++;
                            }
                            System.out.println(str + " after " + iterationCount + " iterations.");
                            }
                            }

                            public static void main(String args) throws InterruptedException
                            {
                            System.out.println("This should print 'Hello world!' and exit if str or iterationCount is volatile.");
                            DelayWrite delay = new DelayWrite();
                            new Thread(delay).start();
                            Thread.sleep(5);
                            System.out.println("Thread sleep gave the thread " + delay.iterationCount + " iterations.");
                            delay.setStr("Hello world!!");
                            }






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 12 at 17:28









                            Aron

                            133




                            133






























                                 

                                draft saved


                                draft discarded



















































                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5816790%2fthe-code-example-which-can-prove-volatile-declare-should-be-used%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                                ComboBox Display Member on multiple fields

                                Is it possible to collect Nectar points via Trainline?