Java基础知识_Lock锁子类了解一下

一、ReentrantLock锁

首先我们来看看ReentrantLock锁的顶部注释,来看看他的相关特性呗。

 

 来总结一下要点吧:

比synchronized更有伸缩性(灵活)

支持公平锁(是相对公平的)

使用最标准用法是在try之前调用lock方法,在finally代码块释放锁

 1 class X {
 2     private final ReentrantLock lock = new ReentrantLock();
 3     // ...
 4 
 5     public void m() { 
 6         lock.lock();  // block until condition holds
 7         try {
 8             // ... method body
 9         } finally {
10             lock.unlock()
11         }
12     }
13 }

1.1 内部类

首先我们可以看到有三个内部类

 

 这些内部类都是AQS的子类,AQS是ReentrantLock的基础,AQS是构建锁和同步器的框架

可以很清晰的看到,我们的ReentrantLock锁是支持公平锁和非公平锁的

 

 1.2 构造方法

 

 1.3 非公平lock方法

尝试获取锁,获取失败的话就调用AQS的acquire(1)方法

 

 acquire(1)方法我们在AQS时简单看过,其中tryAcquire()子类来实现的

我们去看看tryAcquire()

 

 1.4 公平lock方法

公平的lock方法其实就多了一个状态条件:

 

 这个方法主要是判断当前线程是否位于CLH同步队列的第一个,如果是返回false,如果不是返回true

 

 1.5 unlock方法

 

 unlock方法也是在AQS中定义的

 

 去看看tryRelease(arg)是怎么实现的

 

 

二、ReentrantReadWriteLock

我们知道synchronized内置锁和ReentrantLock都是互斥锁(一次只能有一个线程进入到临界区)

而ReentrantReadWriteLock 是一个读写锁

  在读取数据的时候,可以多个线程同时进入到临界区(被锁定的区域)

  在写数据的时候,无论读线程还是写线程都是互斥的

一般来说,我们大多数的时候是读取数据的多,修改数据的少。所以这个读写锁在这种场景下就很有用了。

读写锁有一个接口ReadWriteLock,定义的方法就两个

 

 我们还是来看看顶部注释说了些什么

 

 其实大概也是说明了:在读的时候可以共享,在写的时候是互斥的

接下来我们还是看看对应的实现类吧:

 

 按照惯例也简单看看它的顶部注释:

 

 于是我们可以总结出读写锁的一些要点了:

  读锁不支持条件对象,写锁支持条件对象

  读锁不能升级为写锁,写锁可以降级为读锁

  读写锁也有公平和非公平模式

  读锁支持多个读线程进入临界区,写锁是互斥的

2.1 ReentrantReadWriteLock的内部类

ReentrantReadWriteLock比ReentrantLock锁多了两个内部类(都是Lock实现)来维护读锁和写锁,但是主体还是使用Syn:

1、WriteLock

2、ReadLock

 

 2.2 读锁和写锁的状态表示

在ReentrantLock锁上使用的是state来表示同步状态(也可以表示重入的次数),而在ReentrantLock是这样代表读写状态的。

 

 

2.3 写锁的获取

主要还是调用syn的acquire(1):

 

 进去看看实现

 

 2.4读锁获取

写锁的获取调用的是acquireShared(int arg)方法:

 

 内部调用的是:doAcquireShared(arg);方法(实现也是在Syn的),我们来看看:

 

 三、最后

总结

  • AQS是ReentrantReadWriteLock和ReentrantLock的基础,因为默认的实现都是在内部类Syn中,而Syn是继承AQS的~

  • ReentrantReadWriteLock和ReentrantLock都支持公平和非公平模式,公平模式下会去看FIFO队列线程是否是在队头,而非公平模式下是没有的

  • ReentrantReadWriteLock是一个读写锁,如果读的线程比写的线程要多很多的话,那可以考虑使用它。它使用state的变量高16位是读锁,低16位是写锁

  • 写锁可以降级为读锁,读锁不能升级为写锁

  • 写锁是互斥的,读锁是共享的

总的来说看多线程源码难度系数还是好高啊,我目前的水平只能过一过了….

posted @ 2019-09-20 13:15  chyblogs  阅读(496)  评论(0)    收藏  举报