程序员Java

从happen-before角度分析synchronized与l

2019-12-27  本文已影响0人  yuan_dongj

充电时刻(happen-before八个原则)




推荐阅读: java 8大happen-before原则超全面详解

happen-before不能理解成在什么之前发生,它和时间没有任何关系,解释成“生效可见于” 更准确。即使出现了指令重排,只要符合happen-before规则,那么上文的结果就会对下文生效。

关于内存可见性的疑惑

一个简单的例子

    private static int count;

    public void incr() {
        //加锁
        while(count <= 100) {
            count++;
        }
        //解锁
    }

不知道大家有没有像我一样的疑惑,无论是使用哪种加锁方式,count变量并没有被volatile修饰,那么对count变量的修改是如何保证内存可见性的呢?

好像对这件事是如此的理所应当,就像太阳每天从东方升起,不觉得这有什么好质疑的。

lock的内存可见性

以ReentrantLock公平锁为例,我们看看获取锁 & 释放锁的关键代码

    private volatile int state;

    protected final int getState() {
        return state;
    }

    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        //重要
        int c = getState(); //line 1
        //...竞争锁逻辑忽略
    }

    protected final boolean tryRelease(int releases) {
        int c = getState() - releases;
        // ...根据状态判断是否成功释放,省略

        //写volatile变量,重要
        setState(c); // line 2
        return free;
    }

假设有A,B两个线程执行count++,A线程抢到执行权,B线程阻塞。A线程释放锁时会走line 2,这时B线程继续争抢执行权执行line 1。

synchronized的内存可见性

上一篇 下一篇

猜你喜欢

热点阅读