Semaphore
信号量:控制同时访问某个特定资源的操作数量。
常用方法:
acquire
方法。获取一个许可证,获取不到就阻塞等待。
acquire(int permits)
。一次获取 permits 个许可证。
tryAcquire()
。它会尝试获取一个许可证,如果许可证可用,它会立即获取许可证并返回true,表示成功获取;如果许可证不可用,tryAcquire()方法会立即返回false,而不会阻塞线程。线程可以根据返回值来判断是否成功获取许可证。
tryAcquire(int permits)
。尝试获取 permits 个许可证,获取到返回 true,获取不到返回 false。
tryAcquire(int timout, TimeUnit unit)
。等待一段时间获取一个许可证,如果获取到了就返回 true,获取不到就返回 false。
tryAcquire(int permits, int timout, TimeUnit unit)
。等待一段时间获取 permits 个许可证,如果获取到了就返回 true,获取不到就返回 false。
release()
。归还一个令牌到令牌桶。
release(int permits)
。归还 permits 个令牌到令牌桶。
acquireUninterruptibly
。阻塞式获取一个许可证,不可被中断。
acquireUninterruptibly(int permits)
。阻塞式获取 permits 个许可证,不可被中断。
availablePermits
。返回当前可用的许可的数量。
public class SemaphoreTest {
private final List<String> list;
private final Semaphore semaphore;
public SemaphoreTest(int bound) {
this.list = Collections.synchronizedList(new ArrayList<>());
this.semaphore = new Semaphore(bound);
}
public void add(String str) throws InterruptedException {
// 获取一个许可证
semaphore.acquire();
System.out.println(str + "获取一个许可证");
list.add(str);
System.out.println("向集合添加数据:" + str);
}
public void remove(String str) {
boolean flag = list.remove(str);
if (flag) {
System.out.println("移除元素:" + str);
semaphore.release();
}
}
public static void main(String[] args) {
// 设置两个凭证,每添加一次消耗一个凭证,当凭证获取完后,需要有新元素移除并释放凭证后才能添加
SemaphoreTest semaphoreTest = new SemaphoreTest(2);
try {
semaphoreTest.add("AAA");
// semaphoreTest.remove("AAA");
semaphoreTest.add("BBB");
semaphoreTest.add("CCC");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果为:
AAA获取一个许可证
向集合添加数据:AAA
BBB获取一个许可证
向集合添加数据:BBB