1. 类功能描述
支持最多N个线程同时访问的锁,超时N时将被阻塞
2. 类
部分关键代码如下:
/**
* 最多允许n个线程同时访问,超过n个线程的访问将被阻塞
* @author ouyangrongtao
* @since 2021-12-19 18:21
*/
public class CustomLock implements Lock {
private final Sync sync = new Sync(3);
private static final class Sync extends AbstractQueuedSynchronizer {
public Sync(int count) {
super();
if (count < 0) {
throw new IllegalArgumentException("count must large than zero.");
}
// 设置锁数量
setState(count);
}
@Override
protected int tryAcquireShared(int acquires) {
for (;;) {
// 获取锁个数
int available = getState();
if (available == 0) {
// // 没有锁了,继续自旋
continue;
}
// 增加锁
int remaining = available - acquires;
// cas 修改
if (compareAndSetState(available, remaining)) {
return remaining;
}
}
}
@Override
protected boolean tryReleaseShared(int acquires) {
for (;;) {
// 获取锁个数
int available = getState();
// 释放锁
int remaining = available + acquires;
// cas 修改
if (compareAndSetState(available, remaining)) {
return true;
}
}
}
}
@Override
public void lock() {
sync.tryAcquireShared(1);
}
@Override
public void unlock() {
sync.tryReleaseShared(1);
}
}
3. CustomLock
测试
测试我们自己编写的 CustomLock
,测试类如下:
public class TestCustomLock {
private static final CustomLock lock = new CustomLock();
public static void main(String[] args) throws InterruptedException {
// 启动10个线程
for (int i = 0; i < 10; i++) {
Worker w = new Worker();
w.setDaemon(true);
w.start();
}
// 主线程每隔1秒打印一下
for (int i = 0; i < 100; i++) {
Thread.sleep(1000);
log.info("");
}
}
static class Worker extends Thread {
@Override
public void run() {
while (true) {
lock.lock();
try {
Thread.sleep(1000);
log.info("获取到锁");
Thread.sleep(1000);
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
}
}
测试结果:
20:32:18.668 [Thread-1] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:18.668 [Thread-2] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:18.668 [Thread-0] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:18.668 [main] INFO com.study.lock.TestCustomLock -
20:32:19.739 [main] INFO com.study.lock.TestCustomLock -
20:32:20.752 [Thread-0] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:20.752 [Thread-1] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:20.752 [main] INFO com.study.lock.TestCustomLock -
20:32:20.752 [Thread-2] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:21.753 [main] INFO com.study.lock.TestCustomLock -
20:32:22.766 [Thread-0] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:22.767 [Thread-2] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:22.767 [main] INFO com.study.lock.TestCustomLock -
20:32:22.767 [Thread-5] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:23.777 [main] INFO com.study.lock.TestCustomLock -
20:32:24.792 [Thread-1] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:24.792 [Thread-4] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:24.792 [Thread-8] INFO com.study.lock.TestCustomLock - 获取到锁
20:32:24.792 [main] INFO com.study.lock.TestCustomLock -
实验证明,同一时间只能有3个线程获取锁,其他线程则被阻塞。