1. semaphore
- 可以限制对资源访问的线程数量的上限
基本语法
//设置线程的上限 3
Semaphore semaphore = new Semaphore(3);
//获取一个许可 - 1
semaphore.acquire();
//释放 + 1
semaphore.release();
2. 创建一个测试类SemaphoreTest
package org.example.SemaphoreLock;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@Slf4j
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 15; i++) {
new Thread(() -> {
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
log.info("start...");
TimeUnit.SECONDS.sleep(1);
log.info("end...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}, "t" + i).start();
}
}
}
3. 查看打印结果
- 3组线程执行结束后,才会有3组新的线程再启动。
4. 加锁
- 非公平锁加锁
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
//1. getState()得到state,在设置线程数量的时候set进去的,这里state=3
int available = getState();
//2. 加锁就-1,前3个线程分别等于2、1、0
int remaining = available - acquires;
//3. 前3个线程remaining>=0,进入第二个判断,cas把state分别设置为2、1、0,成功则返回remaining
//4. 如果第4个线程执行到这里,在前3个线程还没有释放之前,available=0,减1则(remaining=-1)<0,不会进入执行cas,直接返回-1
//5. 如果remaining>0,加锁成功,aqs内直接反馈;如果remaining<0,加锁失败,aqs内执行doAcquireSharedInterruptibly(arg)方法,进入队列park排队
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
5. 解锁
- 解锁就是把当前state值+1,然后cas修改state的值