illustrating volatile : is this code thread-safe?

前端 未结 6 941
感动是毒
感动是毒 2020-12-17 05:49

I\'m trying to illustrate the use and importance of volatile with an example that would really not give a good result if volatile was omitted.

6条回答
  •  Happy的楠姐
    2020-12-17 06:44

    It was always hard to me to illustrate concurrency problems in a convincing way: well, fine, it's all nice about happens-before and stuff, but why should one care? Is there a real problem? There are lots and lots of poorly written, poorly synchronized programs—and they still work most of the time.

    I used to find a resort in a "works most of the time VS works" rhetoric—but, frankly, it's a weak approach. So what I needed is an example which would make difference obvious—and, preferably, painful.

    So here is a version which actually does show the difference:

    public class VolatileExample implements Runnable {
        public static boolean flag = true; // do not try this at home
    
        public void run() {
            long i = 0;
            while (flag) {
                if (i++ % 10000000000L == 0)
                    System.out.println("Waiting  " + System.currentTimeMillis());
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(new VolatileExample());
            thread.start();
            Thread.sleep(10000L);
            flag = false;
            long start = System.currentTimeMillis();
            System.out.println("stopping " + start);
            thread.join();
            long end = System.currentTimeMillis();
            System.out.println("stopped  " + end);
            System.out.println("Delay: " + ((end - start) / 1000L));
        }
    }
    

    A simple run shows:

    Waiting  1319229217263
    stopping 1319229227263
    Waiting  1319229242728
    stopped  1319229242728
    Delay: 15
    

    That is, it takes more than ten seconds (15 here) for a running thread to notice there was any change.

    With volatile, you have:

    Waiting  1319229288280
    stopping 1319229298281
    stopped  1319229298281
    Delay: 0
    

    that is, exiting (almost) immediately. The resolution of currentTimeMillis is around 10ms, so the difference is more that 1000 times.

    Note it was Apple's version of (ex-)Sun JDK, with -server option. The 10-second wait was added in order to let JIT compiler find out that the loop is hot enough, and optimize it.

    Hope that helps.

提交回复
热议问题