ReentrantLock

ReenTrantLock可重入锁(和synchronized的区别)总结

 

重入性: ReenTrantLock和synchronized都是可重入锁。 同一个线程每进入一次,锁的计数器+1,等到锁的计数器降为0时才释放锁。

实现:    Synchronized是依赖于JVM实现的,而ReenTrantLock是JDK实现的。

写法:    Synchronized由编译器去保证锁的加锁和释放,而ReenTrantLock需要手工声明来加锁和释放锁,为了避免忘记手工释放锁造成死锁,所以最好在finally中声明释放锁。

锁类型: ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。

ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

 

final Lock lock = new ReentrantLock();//锁对象
final Condition notFull  = lock.newCondition();//写线程条件 
final Condition notEmpty = lock.newCondition();//读线程条件
   
 lock.lock();
 try {
    notFull.await();//阻塞写线程
    //.......
    notEmpty.signal();//唤醒读线程
 } finally {
    lock.unlock();
 }

 

 

Object的                                 wait   notify   notifyAll    FIFO
ReentrantLock 的condition的 await signal  signalAll

 

ReentrantLock主要利用CAS+CLH队列来实现。

CAS:       Compare and Swap,比较并交换。CAS有3个操作数:内存值V、预期值A、要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。该操作是一个原子操作,被广泛的应用在Java的底层实现中。在Java中,CAS主要是由sun.misc.Unsafe这个类通过JNI调用CPU底层指令实现。
CLH队列:带头结点的双向非循环链表

/**
 * 该锁同步控制的一个基类.下边有两个子类:非公平机制和公平机制.使用了AbstractQueuedSynchronizer类的
 */
static abstract class Sync extends AbstractQueuedSynchronizer (AQS)
/**
 * 非公平锁同步器
 */
final static class NonfairSync extends Sync

/**
 * 公平锁同步器
 */
final static class FairSync extends Sync   

/** 同步器:内部类Sync的一个引用 */
private final Sync sync;

/**
 * 创建一个锁
 * @param fair true-->公平锁  false-->非公平锁
 */
public ReentrantLock(boolean fair) {
    sync = (fair)? new FairSync() : new NonfairSync();
}

 

 

 

参考  https://blog.csdn.net/qq838642798/article/details/65441415

posted @ 2019-03-30 13:49  webglcn  阅读(105)  评论(0编辑  收藏  举报