Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
587 views
in Technique[技术] by (71.8m points)

java - using volatile keyword

As i understand, if we declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the values, it is updated to the main memory. So, other threads can access the updated value.

But in the following program both volatile and non-volatile variables are displaying same value.

The volatile variable is not updated for the second thread. Can anybody plz explain this why testValue is not changed.

class ExampleThread extends Thread {
    private int testValue1;
    private volatile int testValue;
    public ExampleThread(String str){
      super(str);
    }
    public void run() {
    if (getName().equals("Thread 1 "))
    {
        testValue = 10;
        testValue1= 10;
        System.out.println( "Thread 1 testValue1 : " + testValue1);
        System.out.println( "Thread 1 testValue : " + testValue);
    }
    if (getName().equals("Thread 2 "))
    {
        System.out.println( "Thread 2 testValue1 : " + testValue1);
        System.out.println( "Thread 2 testValue : " + testValue);
    }               
}
}

public class VolatileExample {
    public static void main(String args[]) {
        new ExampleThread("Thread 1 ").start();
        new ExampleThread("Thread 2 ").start();
    }
}


output:
Thread 1 testValue1 : 10
Thread 1 testValue : 10
Thread 2 testValue1 : 0
Thread 2 testValue : 0
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your variables are confined to a single thread, so there is no other thread accessing them. Thus volatile makes no difference.

If you declared them static, they would be shared between different threads. However, even then you may not be able to observe the difference between your volatile and nonvolatile variable. Quote from Java Concurrency in Practice, chap. 3.1.4:

The visibility effects of volatile variables extend beyond the value of the volatile variable itself. When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable. So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and reading a volatile variable is like entering a synchronized block.

In your case, the code happens to modify the volatile variable first, so the updated value of the other variable may not be visible to the other thread. So far, so good.

However, since you are printing out the values of the variables from the same thread which modified them, you won't see any difference anyway.

Update2: Try this modified version (note: I have not tested it):

class ExampleThread extends Thread {
    private static int testValue1;
    private static volatile int testValue;
    private int newValue;

    public ExampleThread(String str, int newValue){
      super(str);
      this.newValue = newValue;
    }
    public void run() {
      for (int i = 0; i < 10; i++) {
        System.out.println(getName() + " testValue1 before update: " + testValue1);
        System.out.println(getName() + " testValue before update: " + testValue);
        testValue = i * newValue;
        testValue1 = i * newValue;
        System.out.println(getName() + " testValue1 after update: " + testValue1);
        System.out.println(getName() + " testValue after update: " + testValue);
        sleep(10);
      }               
    }               
}

public class VolatileExample {
    public static void main(String args[]) {
        new ExampleThread("Thread 1 ", 5).start();
        new ExampleThread("Thread 2 ", 10).start();
    }
}

Update: regarding the visibility of static fields - again from the same tome (chap 16.2.3):

[...] statically initialized objects require no explicit synchronization either during construction or when being referenced. However, this applies only to the as-constructed state - if the object is mutable, synchronization is still required by both readers and writers to make subsequent modifications visible and to avoid data corruption.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...