java或者其他高级语言中的volatile

我们都知道语言在编译和执行过程中会对自身程序进行优化

如下:

public class Test{

    private static int INIT_VALUE = 0;

    private final static int MAX_VALUE = 5;

    public static void main(String[] args) {
        new Thread(() -> {
            int localValue = INIT_VALUE;
            while (localValue < MAX_VALUE){
                if(localValue != INIT_VALUE){
                    System.out.printf("The value update to [%d]",INIT_VALUE);
                    localValue = INIT_VALUE;
                }
            }
        },"READER").start();

        new Thread(() -> {
            int localValue = INIT_VALUE;
            while(localValue < MAX_VALUE){
                System.out.printf("Update the value to [%d] \n", ++localValue);
                INIT_VALUE  = localValue;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"UPDATER").start();
}

猜猜会输出什么:

Update the value to [1] 
Update the value to [2] 
Update the value to [3] 
Update the value to [4] 
Update the value to [5] 

····

程序挂起

因为2线程启动后会更新INIT_VALUE 导致INIT_VALUE 迅速到5.

线程1 拿到的INIT_VALUE值还是0,java会内部优化此性能导致1线程 死循环

如何解决这个问题?确保INIT_VALUE能够读和写分开执行并且能够让java忽略对该属性的优化。就需要用到 volatile

package com.handsome.thread2study.chapter3;

/**
 * @author jiangkunli
 * @date 2020-07-01 11:47 下午
 * @description
 */
public class VolatileTest {

    private volatile static int INIT_VALUE = 0;

    private final static int MAX_VALUE = 5;

    public static void main(String[] args) {
        new Thread(() -> {
            int localValue = INIT_VALUE;
            while (localValue < MAX_VALUE){
                if(localValue != INIT_VALUE){
                    System.out.printf("The value update to [%d]",INIT_VALUE);
                    localValue = INIT_VALUE;
                }
            }
        },"READER").start();

        new Thread(() -> {
            int localValue = INIT_VALUE;
            while(localValue < MAX_VALUE){
                System.out.printf("Update the value to [%d] \n", ++localValue);
                INIT_VALUE  = localValue;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"UPDATER").start();
    }
}




这样执行会发现 2线程执行+后,1线程随后就会执行updata操作,有序进行
看懂了吗?

小结:

其实

volatile关键字就是将资源锁定,同时只有一个操作来占用源,并且是有序进行。1操作、2操作、3操作、一定不会出现 1操作 1操作无序且重复调用的情况!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章