0

I was confused with a code snippet like this:

public class LearnTest {

private static boolean tag = true;
private static int i = 0;

public static void main(String[] args) {

    new Thread(new Runnable() {
        @Override
        public void run() {
            while (tag) {
                //System.out.println("ok");
                i++;
            }
        }
    }).start();

    try {
        Thread.sleep(1000);
    }catch (Exception e) {
        e.printStackTrace();
    }

    tag = false;
    System.out.println(i);
  }
}

In the code, we have a new-thread and main-thread.The result about this code will be a random value of i and the new-thread will not exit.Because new-thread will not get the new tag value.

if we change the define of tag which will be decorated with volatile, it will print some value of i and new-thread will exit. Because volatile will keep the visibility for all thread.

But when I cannel the comment for the commentted code line,and thetag will not be decorated witch volatile,it will print some "ok" and exit.

why?

what I suppose is that Java's IO will do something like synchronized, it will force the tag side value of new-thread to refresh from main shared memory.

This's corret?

chyoo CHENG
  • 720
  • 2
  • 9
  • 22
  • If you not define as `volatile`, the variable __maybe__ cached by CPU, and maybe NOT, so it no strange if other thread can see it's change. – Yu Jiaao Mar 28 '17 at 14:28

1 Answers1

0

Without volatile the thread is not guaranteed to see changes to the value. It may see them.

In this case adding the System.out.println() results (apparently) in the value being removed from the cache, so it's fetched from the main memory at some point. Without the println() the value remains in cache, and you get the infinite (or at least very long) loop.

That's one difficulty with concurrent programming, sometimes code may appear to work correctly, but there's no way to be certain it always works correctly.

Kayaman
  • 72,141
  • 5
  • 83
  • 121