这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战
基本概念
- 根据锁添加到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