Java内存模型学习之锁的内存语义 ReetrantLock的源码分析 Lock释放锁和获取锁的过程(公平锁和非公平锁)

锁的释放和锁的获取:

线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共享变量所做修改的)消息

线程B获取一个锁,实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共享变量所做修改的)消息

线程A释放锁,随后线程B获取这个锁,这个过程实质上是通过线程A通过主内存向线程B发送消息

package juc.lock;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description 
 * @Author DJZ-WWS
 * @Date 2019/5/13 14:13
 */
public class ReetrantTest {

int  a=0;
    ReentrantLock  lock=new ReentrantLock();
    public   void  writer(){
        //获取锁
        lock.lock();
        try{
        a++;
        }finally {
            //释放锁
            lock.unlock();
        }
    }
    
    public  void  read(){
        lock.lock();//获取锁
   try {
       int i=a;
       i++;
   }finally {
       lock.unlock();//释放锁
   }
       
;    }
   

}

ReentrantLock的实现依赖于java同步器AbstractQueueSynchronizer(习惯简称为AQS),它使用一个整型的volatile变量来维护同步状态,ReentrantLock分为公平锁,不公平锁,类中有如下源码

 

 

这个类图如下:

使用公平锁时,加锁方法LOck调用轨迹如下:

1.ReentrantLock:lock()

2.FairSync:lock()

2.AbstractQueueSynchronizer.acquire(int arg)。

ReentrantLock这个类中自带lock方法,

他的内部类使用了Syn内部类的对象调用了自身的lock方法,

上面的抽象方法有两个实现,一个是公平锁的一个是非公平锁的,这两个锁内部维护着一个lock方法,最终是通过这个最内部的lock方法里面的tryAcquire()方法实现加锁。

这个方法源码如下:

从源码中可以看出加锁方法首先读volatile变量state。

getState()方法如下

返回结果的state是使用volatile 修饰的,

以上便是lock实现对公平锁的调用流程

使用公平锁的时,解锁方法unlock()调用轨迹

1.ReentrantLock:unlock()

2.AbstractQueuedSynchronizer:release(int arg)。

3.Sync:tryRelease(int release)

最后一步真正实现释放锁

        公平锁在释放锁的最后写volatile变量state,在获取锁的时候首先读取这个volatile变量。根据volatile的happen-before规则,释放锁的线程在写volatile之前可见的共享变量,在获取锁的线程读取同一个volatile变量后变得对获取锁的线程可见。

       非公平锁的释放和公平锁完全一样。使用非公平锁加锁的lock的调用轨迹如下:

1>ReentrantLock:lock().

2>NonfairSync:lock();

3>AbstractQueuedSynchronizer:compareAndSetState(int expect,update

第三步的时候实现真正的加锁。

这是NonfairSync内部类的方法调用

它的底层调用了cas原子操作方法,对于cas前面一片文章已经介绍过,不再赘述

公平锁和非公平锁释放时最后都要写一个volatile变量state

公平锁和非公平锁释放时,最后都要写一个volatile变量state

公平锁获取时,首先回去读volatile变量

非公平锁获取时,首先会用CAS更新volatile变量,这个操作同时具有volatile读和volatile的内存语义。

   

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值