ReentranLock底层原理分析

作者: 降龙_伏虎 | 来源:发表于2019-09-26 14:33 被阅读0次

1 J.U.C简介

  • java.util.concurrent 简称,java并发工具包
  • 线程池
  • 阻塞队列
  • 计时器/同步器
  • 并发集合

2 Lock的基本使用

  • synchronized 不够灵活,锁的释放无法人为控制,只能等待同步代码块执行完成或发生异常
  • Lock java.util.concurrent.locks 包下的接口,提供了锁的获得与释放的接口方法,在JUC中存在众多实现
    image.png

3 ReentranLock重入锁

  • 同一线程 通过Lock.lock()获得重入锁,当此线程再次调用时不会被阻塞可以进入,即:同一线程"一次锁定多次进入",其它线程此时调用进行阻塞
  • synchronized 也支持重入
  • ReentranLock重入锁的设计目的是为了解决死锁
public class ThreadDemo1 {

    public synchronized void func1(){//获取对象锁
        System.out.println("func1");
        func2();
    }

    public void func2(){
        synchronized (this){//同一线程,同一把锁允许重入,增加重入次数,并没有死锁
            System.out.println("func2");
        }//同步代码执行完成,减少重入次数
    }

    public static void main(String[] args) {
        ThreadDemo1 demo1 = new ThreadDemo1();
        demo1.func1();
    }
}

public class ThreadDemo2 {
    //重入锁
    static Lock LOCK = new  ReentrantLock();
    
    public void func1(){
        LOCK.lock();//获得重如锁
        //....
        LOCK.unlock();//释放重入锁
    }
}

4 读写锁ReentrantReadWriteLock

  • 适用于读多写少的操作,例如缓存更新
  • 读锁&读锁->可重入
  • 读锁&写锁(写锁&读锁)->阻塞不可重入
public class ThreadDemo3 {
    //读写锁
    static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

    //读锁
    static  ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    //写锁
    static  ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
    //缓存
    static Map<String,Object> cache = new HashMap<String, Object>();

    /**
     * Description:根据key从缓存中获取对象
     * @Param [key]
     * @return java.lang.Object
    **/

    public final Object getFromCache(String key){
        readLock.lock();//获取'读锁'
        try {
            return cache.get(key);
        } finally {
            readLock.unlock();//释放'读锁'
        }
    }

    /**
     * Description:向缓存中添加对象
     * @Param [key, value]
     * @return void
    **/

    public void putToCache(String key,final Object value){
        writeLock.lock();//获取'写锁'
        try {
            cache.put(key,value);
        } finally {
            writeLock.unlock();//释放'写锁'
        }
    }
}

5 AQS原理分析

  • 同步工具
    ReentrantLock 中AQS实现原理

ReentrantLock.Sync(内部类).lock()
Sync有两个子类
FairSync-公平锁(不允许插队)
NonfairSync-非公平锁(允许插队)
分别重写了lock()方法

6 AQS源码分析

6.1 ReentrantLock 获取锁LOCK.lock();//获得重入锁时序图

image.png

6.1 ReentrantLock 获取锁LOCK.lock();//获得重入锁流程图

image.png

相关文章

网友评论

    本文标题:ReentranLock底层原理分析

    本文链接:https://www.haomeiwen.com/subject/occkyctx.html