Lock锁底层原理实现
底层基于AQS+Cas+LockSupport 锁实现
Synchronized与Lock锁之间的区别
Lock基于AQS封装的锁结合CAS实现,而Lock锁的升级过程需要自己实现;
Synchronized是基于C++虚拟机封装,JDK1.6优化可以实现锁的升级过程;
LockSupport的用法
AbstractQueuedsynchronizer(AQS)
- Fairsync ---公平锁
- Nonfairsync-非公平锁
- 父类都是AbstractQueuedsynchronizer
ReentrantLock默认情况下都是非公平锁
公平锁/非公平锁原理在此不做介绍
AQS实现原理
状态:0,1 5,7>1 当前线程重入+1
状态:0===当前我们锁没有被任何线程持有状态:
0===1锁已经被其他线程持有
有一个没有获取到锁的线程集合(双向链表实现)。
Node结点采用双向链表的形式存放正在等待的线程waitStatus 状态、thread等到锁的线程
- CANCELLED值为-1,表示当前的线程被取消
- SIGNAL 释放资源后需唤醒后续节点
- CONDITION,值为-2,等待condition唤醒;
- PROPAGATE
- 值为-3,工作于共享锁状态,需要向后传播,比如根据资源是否剩余,唤醒后继节点;
- 值为0,表示当前节点在sync队列中,等待着获取锁。
- Head 头结点等待队列的头结点
- Tail尾结点正在等待的线程
- State锁的状态0无锁、1已经获取锁,当前线程重入不断+1
- exclusiveOwnerThread 记录锁的持有
Cas+LockSupport+AQS手写Lock锁
package com.example.test.study;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
/**
* @author Wcy
* @Date 2022/10/6 20:19
*/
public class MyLock {
/**
* 0表示未锁定,1表示锁定
*/
private AtomicInteger lockState = new AtomicInteger(0);
/**
* 获取到锁的线程
*/
private Thread lockCurrentThread = null;
/**
* 等待队列
*/
private ConcurrentLinkedDeque<Thread> waiters = new ConcurrentLinkedDeque<>();
/**
* 获取锁
*/
public void lock() {
acquire();
}
public boolean acquire() {
while(true) {
if (lockState.compareAndSet(0, 1)) {
lockCurrentThread = Thread.currentThread();
//获取锁成功
return true;
}
//获取锁失败
waiters.add(Thread.currentThread());
//阻塞当前线程
LockSupport.park();
}
}
public boolean compareAndSet(int expect, int update) {
return lockState.compareAndSet(0, 1);
}
/**
* 释放锁
*/
public boolean unlock() {
if (lockCurrentThread == null) {
return false;
}
if (lockCurrentThread == Thread.currentThread()) {
boolean res= compareAndSet(1, 0);
if(res){
//公平锁唤醒 链表第一个
Thread first = waiters.getFirst();
if (first != null) {
LockSupport.unpark(first);
}
//非公平锁唤醒 全部唤醒
//waiters.forEach(t -> {
// LockSupport.unpark(t);
//});
return true;
}
}
return false;
}
}
Semaphore信号量底层原理
本质基于AQS做封装
CountDownLatch原理
CountDownLatch源码分析
CountDownLatch是一种java.util.concurrent包下一个同步工具类,它允许一个或多个线程等待直到在其他线程中一组操作执行完成。和join方法非常类似
CountDownLatch 底层是基于AQS实现的
CountDownLatch countDownLatch=new CountDownLatch(2)AQS的state状态为2
调用countDownLatch.countDown();方法的时候状态-1当AQS状态state为0的情况下,则唤醒正在等待的线程。
此处评论已关闭