2022-09-25并发编程系列00

ReentrantLock源码解析

ReentrantLock

参考文档

ReentrantLock介绍

ReentrantLock,意思是“可重入锁”,关于可重入锁的概念在下一节讲述。ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法。

基本语法上,ReentrantLock与synchronized很相似,它们都具备一样的线程重入特性,只是代码写法上有点区别而已。一个表现为API层面的互斥锁(Lock),一个表现为原生语法层面的互斥锁(synchronized)。

ReentrantLock相对synchronized而言还是增加了一些高级功能,主要有以下三项:

  • 等待可中断:当持有锁的线程长期不释放锁时,正在等待的线程可以选择放弃等待,改为处理其他事情,它对处理执行时间非常长的同步块很有帮助。而在等待由synchronized产生的互斥锁时,会一直阻塞,是不能被中断的。
  • 可实现公平锁:多个线程赶在等待同一个锁时,必须按照申请锁的时间顺序排队等待,而非公平锁则不保证这点,在锁释放时,任何一个等待锁的线程都有机会获得锁。synchronized中的锁是非公平锁,ReentrantLock默认情况下也是非公平锁,但可以通过构造方法ReentrantLock(true)来要求使用公平锁。
  • 锁可以绑定多个条件:ReentrantLock对象可以同时绑定多个Condition对象(条件变量或条件队列),而在synchronized中,锁对象的 wait()和notify()或notifyAll()方法可以实现一个隐含条件,但如果要和多于一个的条件关联的时候,就不得不额外地添加一个锁,而ReentrantLock则无需这么做,只需要多次调用newCondition()方法即可。而且我们还可以通过绑定Condition对象来判断当前线程通知的是哪些线程(即与Condition对象绑定在一起的其它线程)。
2022-09-25并发编程系列00

StampedLock

参考文档

基本介绍

该类自 JDK 8 加入,是为了进一步优化读性能,它的特点是在使用读锁、写锁时都必须配合 使用

StampedLock提供三种模式的读写锁,分别为写锁、悲观读锁、乐观读锁。并且是写写互斥、读写互斥、读读共享。

StampedLock 独占写锁:writeLock

writeLock,是排它锁、不可重入锁、也叫独占锁,相同时间只能有一个线程获取锁,其他线程请求读锁和写锁都会被阻塞,当前没有线程持有读锁或写锁的时候才可以获得获取到该锁。

tryWriteLockwriteLock 类似,唯一的区别就是它非阻塞的特性,当获取不到锁时不会阻塞线程但是会返回一个stamp = 0的标识。 stamp > 0 表示成功获取到锁;stamp = 0 表示未获取到锁,但不会阻塞线程 想要开锁(释放锁)必须使用对应的钥匙(stamp)

  • StampedLock 不支持条件变量
  • StampedLock 不支持可重入