JUC锁基本概念
基本概念
- 根据锁添加到Java中的时间 ,Java中的锁分为同步锁和JUC包中的锁JUC锁
同步锁
-
通过synchronized关键字来进行同步,来实现对资源进行互斥访问的锁
-
同步锁的原理:
- 对于每一个对象有且仅有一个同步锁
- 不同的线程都可以访问同步锁,但是在同一个时间点,有且只有一个线程可以获取到同步锁
- 获取到同步锁的线程可以进行CPU调度,从而在CPU上执行线程
- 没有获取到同步锁的线程必须进行等待,直到获取到同步锁之后才可以继续运行
JUC锁
-
JUC中的锁包括:
-
Lock接口
-
ReentrantLock独占锁
-
ReadWriteLock接口
-
ReentrantReadWriteLock读写锁
-
LockSupport阻塞原语
-
Condition条件
-
三个抽象类:
- AbstractOwnableSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedLongSynchronizer
-
其余包括CountDownLatch, CyclicBarrier和Semaphore是通过AQS实现的
-
Lock
-
JUC包中的Lock接口支持语义不同的锁
-
语义不同是指锁可以有公平机制的锁,非公平机制的锁,可重入的锁等
-
公平机制的锁:
- 不同线程获取锁的机制是公平的
-
非公平机制的锁:
- 不同线程获取锁的机制是非公平的
-
可重入的锁:
- 一个锁可以被一个线程多次获取
ReentrantLock
-
ReentrantLock是一个独占锁,同一个时间点只能被一个线程获取到
-
ReentrantLock锁包括公平的ReentrantLock和非公平的ReentrantLock:
- 公平的ReentrantLock: 不同线程获取锁的机制是公平的
- 非公平的ReentrantLock: 不同的线程获取锁的机制是非公平的
-
ReentrantLock是一个可重入的锁
-
ReentrantLock的UML图:
-
ReentrantLock实现了Lock接口
-
ReentrantLock中有一个Sync类型的成员变量sync
-
Sync是一个抽象类,继承自AQS类
-
ReentrantLock中有公平锁类FairSync和非公平锁类NonfairSync. 都是Sync的子类
-
ReentrantLock默认是非公平锁
ReentrantReadWriteLock
-
ReentrantReadWriteLock是读写锁接口ReadWriteLock的实现类,包括子类ReadLock和WriteLock
- ReadLock是共享锁
- WriteLock是独占锁
-
ReentrantReadWriteLock的UML图:
-
ReentrantReadWriteLock实现了ReadWriteLock接口
-
ReentrantReadWriteLock中包含Sync对象,读锁ReadLock和写锁WriteLock. 读锁ReadLock和写锁WriteLock都实现了Lock接口
-
ReentrantReadAndWriteLock中包含一个Sync类型的成员变量sync.Sync是一个抽象类,继承自AQS.Sync中也包含公平所FairSync和非公平锁NonfairSync
ReadWriteLock
- ReadWriteLock接口定义了读取者共享而写入者独占的锁
- JUC包中的ReentrantReadWriteLock实现类该接口
- 可以自定义ReadWriteLock锁的实现
LockSupport
- LockSupport提供了创建锁和其余同步类的基本线程阻塞原语
- LockSupport的功能类似于线程Thread中的Thread.suspend() 和Thread.resume()
- LockSupport中有park() 和unpark() 方法分别是阻塞进程和解除阻塞进程,但是不会遇到死锁的情况
Condition
- Condition需要和Lock联合使用.作用是用来代替Object监视器方法,可以通过await() 来休眠和signal() 来唤醒线程
- Condition接口中定义了与锁相关联的条件变量.这些变量的用法类似于Object访问的隐式监视器,但是功能更加强大
- 一个Lock接口可能于多个Condition对象相关联
AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer就是AQS类
- 用来定义锁以及依赖于排队阻塞进程的其余的同步器
- ReentrantLock, ReentrantReadWriteLock, CountDownLatch, CyclicBarrier和Semaphore类都是基于AQS类实现的
AbstractQueuedLongSynchronizer
- AbstractQueuedLongSynchronizer类功能和AbstractQueuedSynchronizer类似
- AbstractQueuedLongSynchronizer提供了对64位的支持
AbstractOwnableSynchronizer
- AbstractOwnableSynchronizer类用于记录当前保持独占的同步线程
- AbstractQueuedSynchronizer和AbstractQueuedLongSynchronizer都实现自AbstractOwnableSynchronizer类
CountDownLatch
- CountDownLatch是一个同步辅助类,在完成一组正在其余线程中执行的操作之前,允许一个或者多个线程一直等待
- CountDownLatch的UML图:
- CountDownLatch中包含了Sync类型的sync对象 .CountDownLatch是Sync的一个实例,继承自AQS
CyclicBarrier
-
CyclicBarrier是一个同步辅助类,允许一组线程相互等待,直到到达某个公共屏障点common barrier point
-
因为barrier在释放等待线程后可以重用,所以称作循环barrier
-
CyclicBarrier包含ReentrantLock类型的lock和Condition类型的trip. 是通过独占锁实现的
-
CyclicBarrier和CountDownLatch的区别:
- CyclicBarrier则是允许N个线程相互等待 ; CountDownLatch的作用是允许1个或者N个线程等待其余线程完成执行
- CyclicBarrier的计数器可以被重置后使用,因此称作可循环的barrier; CountDownLatch的计数器无法被重置
Semaphore
-
Semaphore是一个计数信号量,本质是一个共享锁
-
信号量中维护一个信号量许可集:
- 线程可以通过调用acquire() 来获取信号量的许可
- 当信号量中有可用的许可时,线程可以获取该许可; 否则线程必须等待,直到有可用的许可为止
- 线程可以通过调用release() 来释放所持有的信号量许可
-
Semaphore的UML图:
-
Semaphore包含Sync类型的sync对象
-
Sync继承自AQS抽象类,包括公平信号量FairSync和非公平信号量NonfairSync