volatile解决什么问题

 问题

测试线程安全问题,下面代码,main线程会一直死循环,不会进入判断break。这是为什么呢?

/**
 * Java内存模型,理解volatile解决,线程工作内存不一致问题
 * 工作内存:线程的working memory是cpu的寄存器和高速缓存的抽象描述
 * volatile: 保证每次使用变量,都是先从主内存上刷新到本地内存。所以,保证了可见性。
 */
public class JMM {

    public static void main(String[] args) throws InterruptedException {
        final Trigger trigger = new Trigger();
        trigger.start();

        for (;;) {
            //System.out.print("."); //此处输出代码,会导致trigger能读到 start = true, 这是为什么呢?
            /**
             * 上述问题解释:线程的working memory只是cpu的寄存器和高速缓存的抽象描述。如果死循环读取,就会一致读取到高速缓存区的数据。
             * 而缓存的数据就是start = false, 导致此循环一致无法结束。除非 Trigger 类的属性start用volatile修饰。
             * 问题来了,那么什么情况下,工作内存才会被刷新呢?
             *
             */
            if (trigger.isStart()) {
                System.out.println(Thread.currentThread().getName() + " trigger is start:启动成功");
                break;
            }
        }
    }
}

/**
 * 思考:
 * 1、volatile 保证了可见、有序,但是不能保证原子。所以还是会有线程安全问题,如:i++
 * 2、但是操作boolean,以及赋值操作,天然是原子操作。结合上volatile,就没有了线程安全问题
 */

class Trigger extends Thread {

    private boolean start = false;
    //private volatile boolean start = false;

    public boolean isStart() {
        return start;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " get trigger start:" + start);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Thread.currentThread().getName() + " trigger set start = true");
        start = true;
    }
}

原因 

了解java内存模型,每个线程都有自己的工作内存,工作内存都会从主内存拷贝一份变量(本质上就是高速缓存,这样设计就是为了更好的运行速度),上述循环一致读的是工作内存中的变量。这就是可见性问题,voliatile就是解决此问题的。

原理

volatile: 保证每次使用变量,都是先从主内存上刷新到本地内存。所以,保证了可见性。

线程安全

1. volatile 保证了可见、有序,但是不能保证原子。所以还是会有线程安全问题,如:i++
2. 但是操作boolean,以及赋值操作,天然是原子操作。结合上volatile,就没有了线程安全问题

参考:线程的缓存何时刷新? - 简书

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值