package com.wyh.lock.Test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
@Slf4j(topic = "c.FairyLock")
public class FairyLock {
/**
* 1.默认线程状态
*/
private AtomicInteger lockState = new AtomicInteger(0);
/**
* 2.持有锁对象
*/
private Thread ownerLockThread;
/**
* 3.记录重入次数
*/
private volatile int recursions;
/**
* 4.没有获取锁的线程
*/
private LinkedBlockingDeque<Thread> noLockThreadList = new LinkedBlockingDeque<>();
/**
* 5.加锁
*/
public void lock() throws InterruptedException {
/**
* 4.1当前持锁对象不为空,为当前线程+1
*/
if (ownerLockThread != null && ownerLockThread == Thread.currentThread()) {
recursions++;
return;
}
/**
* 4.2第一次获取锁
* 如果cas次数>10次加入阻塞队列
*/
int spinCount=0;
for (; ; ) {
//4.3cas次数过多,阻塞——>该过程为重型锁
if(spinCount>10){
noLockThreadList.offer(Thread.currentThread());
LockSupport.park();
}
//4.4轻量型锁过程
if (lockState.compareAndSet(0, 1)) {
ownerLockThread = Thread.currentThread();
recursions++;
log.debug("{}获取到锁...", ownerLockThread);
return;
}
//4.4自旋次数+1
Thread.sleep(100);
spinCount++;
}
}
/**
* 5.解锁
*/
public void unlock() throws Exception {
/**
* 5.1如果不是当前线程获取到的锁,抛出异常
*/
if (ownerLockThread != Thread.currentThread()) {
throw new Exception("当前线程没有获取到锁,无法进行释放");
}
/**
* 5.2获取到锁,可重入次数-1
*/
recursions--;
if (recursions == 0) {
for (; ; ) {
if (lockState.compareAndSet(1, 0)) {
//唤醒正在阻塞的线程,阻塞队列的线程进入获取锁状态
log.debug("开始唤醒阻塞队列中的线程");
notifyNotLockThread();
return;
}
}
}
}
/**
* 6.唤醒阻塞队列中的线程(非公平)
*/
private void notifyNotLockThread() {
for (Thread thread : noLockThreadList) {
log.debug("开始唤醒阻塞中的线程{}",Thread.currentThread());
LockSupport.unpark(thread);
}
}
public static void test() throws Exception {
FairyLock wu_lock = new FairyLock();
try {
log.debug("{}开始获取锁",Thread.currentThread());
wu_lock.lock();//主线程获取到锁
//7.1子线程操作
new Thread(()->{
log.debug("{}开始获取锁",Thread.currentThread());
try {
wu_lock.lock();//这里被阻塞住了
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("{}获取锁结束",Thread.currentThread());
},"t1").start();
//7.2主线程操作
log.debug("主线程开始模拟...");
Thread.sleep(500);
log.debug("主线程模拟完毕...");
} catch (Exception e) {
e.printStackTrace();
} finally {
//7.3解锁
wu_lock.unlock();
}
}
public static void main(String[] args) throws Exception {
test();
}
}