首页 > 编程语言 > 详细

多线程(9)volatile的使用

时间:2020-06-22 17:50:45      阅读:58      评论:0      收藏:0      [点我收藏+]

可见性: 直接操作主内存,不需要通过工作内存中转,保证了可见性

原子性:它的读和写单独操作是原子的,但是读和写一起就是非原子操作

禁止重排序:volatile修饰的变量操作位置固定,前面的不能到它后面,它后面的也不能去它前面执行

更多: https://www.jianshu.com/p/9abb4a23ab05

不适用场景

a++  : 非原子的会出错,先读取值得基础上加一赋值

适用场景:

(1)flag = true: 如果一个变量只是被各线程赋值,没有基于先读的基础再写的操作,赋值是原子的,本身有可见性可以代替synchronize实现线程安全

(2)触发器: 底层原理是内存栅栏,也叫屏障指令,说白了就是可以保证线程内存和主内存之间的同步。用了volatile之后,编译器和CPU会识别到,于是就有了同步的功效,

                       可以保证在读取volatile修饰的变量的时候,保证能看到之前的所有写操作,于是就能当作触发器使用。

public class VolatileTest {
    public static void main(String[] args) {
        while (true){
            Vis vis = new Vis();
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    vis.setVal();
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    vis.print();
                }
            });
            t1.start();
            t2.start();
        }

    }
}
class Vis{
    int a=0;
    int c = 0;
    volatile int b=0;
    public void setVal(){
        c = 2;
        a=3;
        b=a;  // 前面的非volatile变量操作也都可见
    }

    public void print(){
            System.out.println("b:"+b+",a:"+a+",c="+c); // 要先读取b,才能保证前面的可见性
    }
}

 

多线程(9)volatile的使用

原文:https://www.cnblogs.com/t96fxi/p/13177765.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!