The Characteristics and Proof of volatile Keyword

Keywords: Java Programming

volatile is a lightweight synchronization mechanism provided by java virtual machine

JMM (Java Memory Model) is built around the three characteristics of atomicity, visibility and orderliness in concurrent programming.

Atomicity: One or more operations are either fully executed and the execution process is not interrupted or not executed.

Visibility: When multiple threads access the same variable at the same time, one thread modifies the value of the variable, and other threads can immediately see the modified value.

Orderliness: The sequence of program execution follows the sequence of code execution.

 

volatile guarantees visibility, orderliness, and no atomicity

 

Code to prove visibility:

 1 package concurrent;
 2 
 3 import java.util.concurrent.TimeUnit;
 4 
 5 /*
 6  * @description: volatile Characteristic
 7  * @date 2019.04.22 20:48
 8  */
 9 //Data class
10 class Mydata{
11 
12     volatile int num = 0;
13 
14     public void changeNum(){
15         this.num = 100;
16     }
17 }
18 
19 public class VolatileDemo {
20 
21     public static void main(String[] args)  throws InterruptedException{
22         Mydata mydata = new Mydata();
23         new Thread(() -> {
24             System.out.println("===="+Thread.currentThread().getName() +"Thread start===");
25             //Pause for 3 seconds.
26             try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {}
27             //3 Seconds later t1 Thread change num Value
28             mydata.changeNum();
29             System.out.println(Thread.currentThread().getName()+"Thread will num The value is changed to"+mydata.num);
30         },"t1").start();
31 
32         //num If the value of the value is unchanged, it will continue to circulate.
33         long begin = System.currentTimeMillis();
34         while (mydata.num == 0){
35             //num If not volatile Modification will go on and on.
36         }
37         long cost = System.currentTimeMillis() - begin;
38         System.out.printf(Thread.currentThread().getName()+"Thread detection num The value has changed.,cost{%d},Proved volatile Visibility",cost);
39     }
40 }

The results are as follows:

==== t1 thread startup===
t1 thread changes num to 100
The main thread detects that the value of num has changed, and the cost{3001} proves the visibility of volatile.

  

Codes that prove that atomicity is not guaranteed:

class Mydata{

    volatile int num = 0;

    public void changeNum(){
        this.num = 100;
    }

    public void numIncreOne(){
        this.num++;
    }
}

public class VolatileDemo {
    
    public static void main(String[] args)  throws InterruptedException{

        Mydata mydata = new Mydata();
        //Open 10 threads and call 1000 times per thread num++
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    mydata.numIncreOne();
                }
            },String.valueOf(i)).start();
        }

        //output num Value,If volatile Ensuring atomicity num It will be equal to 10000.
        System.out.println(mydata.num);
        System.out.println(mydata.num ==10000?"volatile Atomicity can be guaranteed":"volatile No guarantee of atomicity");
    }
}

Output results:

5856
volatile does not guarantee atomicity

 

In a multi-threaded environment, threads are executed alternately, and the compiler optimizes them by reordering the designations. Variables modified by volatile do not participate in reordering to ensure orderliness.

Codes that prove orderliness:

 1     int num = 0;
 2 
 3     private boolean flag = false;
 4     
 5     private void reSort1(){
 6         num = 1;    //Statement 1
 7         flag = true; //Statement 2
 8     }
 9 
10     private void reSort2(){
11         if(flag){
12             num++;
13             System.out.println("num The value is"+num);
14         }
15     }
In multithreading, it is possible to execute statement 2 first and then statement 1, which results in num increasing only once and output 1.

Posted by nou on Mon, 22 Apr 2019 09:03:35 -0700