目标:使用AQS实现简单的Semaphore信号锁
信号锁实现:
- tryAcquireShared:尝试获取许可
- tryReleaseShared:尝试释放许可
代码:
package com.miracle.study.syn;
import org.junit.jupiter.api.Test;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
/**
* @author Miracle
* @date 2021/4/13 21:37
*/
public class SemaphoreTest extends AbstractQueuedSynchronizer {
/**
* 设置最大可通过许可值
* @param size
*/
public SemaphoreTest(int size){
setState(size);
}
/**
* 获取许可
* @param arg
* @return
*/
@Override
protected int tryAcquireShared(int arg) {
var available = getState();
// 判断许可是否为空
if (available != 0){
// 许可减一
var left = available - 1;
// 尝试进行修改许可值
if (compareAndSetState(available, left)){
// 修改成功返回
return left;
}
}
return -1;
}
/**
* 释放许可
* @param arg
* @return
*/
@Override
protected boolean tryReleaseShared(int arg) {
var available = getState();
// 修改现有许可值
return compareAndSetState(available, available + 1);
}
public static void main(String[] args) throws InterruptedException {
var semaphore = new SemaphoreTest(3);
for (int i = 0; i < 50; i++){
new Thread(() -> {
// 获取许可
semaphore.acquireShared(0);
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
// 释放许可
semaphore.releaseShared(0);
}).start();
}
Thread.sleep(5000);
}
}