锁的内存语义

本文将结合源码分析锁的底层实现机制,对于基本的使用不介绍

锁的内存语义

众所周知,锁可以让临界区互斥执行。在这里将介绍锁的另一个功能:锁的内存语义

锁是java中并发编程中非常重要的同步机制,锁除了临界区的互斥执行,还可以完成线程间的通信,如下代码
 

class MonitorExample{
        int a = 0;
        public synchronized void writer(){//1
            a++;//2
        }//3
        public synchronized void reader(){//4
            System.out.println(a);//5
        }//6
    }

根据我们的happens-before(以下简称HB)规则,这个过程的happens-before关系可以分为三类

  • 根据程序次序规则  1 HB 2 ,2 HB 3;4 HB 5,5 HB 6
  • 根据监视器锁规则 3  HB 4
  • 根据传递性:2 HB 5

因此,如果线程A获取锁执行writer后释放锁,线程B执行reader能够得到正确的值,保证了共享变量的可见性

锁的释放与获取内存语义

当线程释放锁时,JMM会把该线程本地内存的共享变量刷新到主存,线程获取 锁时,JMM会将本地缓存置为无效,使得临界区的代码需要从主存重新读取

锁内存语义的实现

这里以ReentrantLock的源码为例分析实现机制,使用lock方法加锁,unLock释放锁,深入源码,我们会发现锁的内部其实维护了一个队列同步器(AQS),如下类图:

在AQS的内部维护了一个整形的volatile变量,ReentrantLock分为公平锁与非公平锁,先看下公平锁,看下调用轨迹

加锁调用轨迹,ReentrantLock.lock(),  FairSync.lock()  AbstactQueueSynchonized.acquire(int arg),ReentrantLock.tryAcquire(int acquires),这一步开始真正的获取锁:加锁方法首先读取volatile变量state,释放锁是写volatile变量state
 

protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

其中有行代码compareAndSetState,有没有感觉很熟悉,compareAndSet不就是我们使用的CAS操作嘛,这里采用CAS来保证以原子的方式更新state变量

最后我们可以看下整个并发包都是在CAS与volatile变量的基础上建立的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值