java锁 aqs_锁和AQS

定义

package java.util.concurrent.locks;

import java.util.concurrent.TimeUnit;

public interface Lock {

void lock();

void lockInterruptibly() throws InterruptedException;

boolean tryLock();

boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

void unlock();

Condition newCondition();

}

优点

持续等待-lock()

可中断-lockInterruptibly()

非阻塞-tryLock() 没有公平可言!

可超时-tryLock(long time, TimeUnit unit)

非阻塞块使用

任意链式锁:a+、b+、c+、a-、c-、b-

缺点

有使用要求

Lock l = ...;

l.lock();

try {

// access the resource protected by this lock

} finally {

l.unlock();

}}

特点

定义了锁的基本使用需求方法:独占(如定时任务)或者保持时序(如计时器)

普通接口+普通实现类:意味着任何人都可以实现

纯code实现,没有特殊的JVM底层支持

提供了抽象支持AbstractQueuedSynchronizer

如何实现

使用一个标志位表示锁是否被获取

使用一个数据结构保存等待的线程

AbstractQueuedSynchronizer

使用int表示状态,支持重入

使用CLH变种队列实现等待队列:双向链表,pre可靠,状态保存在前继节点中,有虚拟头节点

支持独占和共享模式

使用LockSupport进行线程阻塞

状态变量

使用int表示状态,更具拓展性

CLH队列

使用反向单链表实现

公平锁

不断自旋,获取前继节点状态

独占模式和共享模式

独占模式只支持一个线程获取锁:ReentrantLock

共享模式支持多个线程同时获取锁:Semaphore

LockSupport

park 阻塞线程

unpark 取消阻塞线程

AQS实现-ReentrantLock

可重入,独占模式

通过Sync继承AbstractQueuedSynchronizer,实现独占获取和释放

Sync具体实现分为公平和非公平两种,区别在于获取时是否能插队

ReentrantLock实现Lock接口,具体实现调用Sync

dfdab726be262b05bf303604e1b97e22.png

公平锁

lock细节

没人排队,尝试获取锁

自己在排队,重入

别人在排队,自己进入队列,设置pre状态,park

unlock细节

必须是获得锁的线程,不然报错

释放状态,如果完全释放,解除独占线程

如果完全释放,唤醒第一个等待线程

AQS实现-Semaphore

不可重入,共享模式

初始化一个状态值,获取时判断状态值是否超过最大值,超过获取失败,不超过获取成功

2d2874a04da34e52f50d1c2955a26b05.png

AQS实现-CountDownLatch

初始化一个状态值,每次countDown的时候释放1

await等待获取锁,当countDown完成后,await获取锁成功

9ff1a34e29b833a77a3cc70ac6231b10.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值