2022年1月17日
什么是AQS?
AQS(AbstractQueuedSynchronizer)是一个抽象同步框架,可以用来实现一个依赖状态的同步器。
AQS具备的特性:
AQS内部维护属性volatile int state
State三种访问方式:
AQS定义两种资源共享方式
AQS定义两种队列
AQS 定义了5个队列中节点状态:
- 值为0,初始化状态,表示当前节点在sync队列中,等待着获取锁。
- CANCELLED,值为1,表示当前的线程被取消;
- SIGNAL,值为-1,表示当前节点的后继节点包含的线程需要运行,也就是unpark;
- CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队列中;
- PROPAGATE,值为-3,表示当前场景下后续的acquireShared能够得以执行;
条件等待队列
AQS中条件队列是使用单向列表保存的,用nextWaiter来连接:
ReentrantLock设计精髓
- ReentrantLock加锁解锁的逻辑
- 公平和非公平,可重入锁的实现
- 线程竞争锁失败入队阻塞逻辑和获取锁的线程释放锁唤醒阻塞线程竞争锁的逻辑实现 ( 设计的精髓:并发场景下入队和出队 *** 作)
问题:
非公平锁性能更高,相比更少的上下文切换,带来更高的性能
获取锁和加锁的区别
公平锁直接放入队列了,非公平锁会先尝试获取锁,获取不到再放入队列
Sychronized是JVM层面实现,ReentrantLock是Java实现;
ReentrantLock提供了多样化的同步,在激烈的并发性能能维持常态,Sychronized在竞争不激烈的情况下性能较好,在激烈并发下性能下降厉害;
Sychronized先自旋实在不行再上锁,ReentrantLock是直接锁住,带来较多的上下文切换消耗;
两者都支持非公平锁
一般队列只能保证一个有效的长度,超过长度后就无法保留了,阻塞队里可以通过阻塞保留继续入队的任务,阻塞队列自带阻塞和唤醒功能,不需要额外处理,无任务执行时,线程池利用阻塞队列的take方法挂起,从而维持核心线程的存活,不至于一直占有cpu资源。
线程池最大的好处是尽可能的复用线程,减少开销,而且创建线程需要切换到内核态,锁住其他线程,影响其他线程
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)