5. java 锁

本文详细介绍了Java中的锁机制,包括AQS(抽象队列同步器)的应用,加锁解锁流程,以及不同类型的锁如偏向锁、轻量级锁和重量级锁的工作原理和优缺点。还探讨了Synchronized与ReentrantLock的区别,并提到了自旋锁和锁优化策略。
摘要由CSDN通过智能技术生成

锁分类

在这里插入图片描述

1. AQS(抽象队列同步器)

在这里插入图片描述
同步队列(即阻塞队列,线程处于blocked状态,头结点是获取了锁的节点)和等待队列(线程处于waiting状态),等待队列的节点/线程被执行signal()加入同步队列

公平锁只有同步队列的第一个节点能获取锁,非公平锁只有第一个或尚未加入的能获取锁;公平锁和非公平锁区别在于判断当前节点是否有前置节点
锁实际上是通过内部类Sync(即同步器;子类FairSync和NonfairSync)实现,而Sync继承自AbstractQueuedSynchronizer(AQS),AQS通过内部类Node(同步队列和等待队列的节点)和ConditionObject(条件获取锁)来实现锁的功能
在这里插入图片描述

在这里插入图片描述

应用

reentrantlock,CountDownLatch,CyclicBarrier,Semaphore中使用

加锁解锁流程

获取锁

(ReentrantLock.lock()调用sync.acquire(1);acquire先tryAcquire,检查有无前置节点(公平锁),cas修改state状态;若成功则获取锁成功并返回;若失败则调用addWaiter加入同步队列,然后acquireQueued会判断addWaiter添加的节点如果是前驱节点是头节点,并且能够获得同步状态的话,当前线程能够获得锁该方法执行结束退出;否则先将节点状态设置成SIGNAL,然后调用LookSupport.park方法使得当前线程阻塞。)
(获取失败加入同步队列)

释放锁

释放指定量的资源,如果彻底释放了(即state=0),它会唤醒同步队列里的其他线程来获取资源。(ReentrantLock.unlock()调用sync.release(1);release()先更新state,若更新后为0,则获取head节点,调用unparkSuccessor(h);unparkSuccessor调用LockSupport.unpark(head的next节点.thread)唤醒同步队列的下一节点,使其尝试获取锁)
(唤醒同步队列下一节点,从同步队列取出)

Node节点状态(waitStatus):

  1. CANCELLED:值为1,在同步队列中等待的线程等待超时或被中断,需要从同步队列中取消该Node的结点,其结点的waitStatus为CANCELLED,即结束状态,进入该状态后的结点将不会再变化。
  2. SIGNAL(同步队列中):值为-1,被标识为该等待唤醒状态的后继结点,当其前继结点的线程释放了同步锁或被取消,将会通知该后继结点的线程执行。说白了,就是处于唤醒状态,只要前继结点释放锁,就会通知标识为SIGNAL状态的后继结点的线程执行。
  3. CONDITION(等待队列中):值为-2,与Condition相关,该标识的结点处于等待队列中,结点的线程等待在Condition上,当其他线程调用了Condition的signal()方法后,CONDITION状态的结点将从等待队列转移到同步队列中, 等待获取同步锁。
  4. PROPAGATE:值为-3,与共享模式相关,在共享模式中,该状态标识结点的线程处于可运行状态。

加入等待队列/条件队列

condition是要和lock配合使用的也就是condition和Lock是绑定在一起的
使用场景
阻塞队列BlockingDeque

加入等待队列/条件队列
condition.await()方法后会使得当前获取lock的线程进入到等待队列,直至被signal/signalAll后会使得当前线程从等待队列中移至到同步队列中去,直到获得了lock后才会从await方法返回,或者在等待时被中断会做中断处理。

从等待队列中取出
调用condition的signal或者signalAll方法可以将等待队列中等待时间最长的节点移动到同步队列中,使得该节点能够有机会获得lock。

同步队列为什么是双向链表,而等待队列是单链表?

在队列同步器中,头节点是成功获取到同步状态的节点,而头节点的线程释放了同步状态后,将会唤醒其他后续节点,后继节点的线程被唤醒后需要检查自己的前驱节点是否是头节点,如果是则尝试获取同步状态。

final 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值