1.Semaphore 意思
Semaphore 通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。
2.Semaphore 常用方法
acquire()
获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直处于阻塞状态。
acquire(int permits)
获取permits(多个)个令牌,在获取到令牌、或者被其他线程调用中断、或超时之前线程一直处于阻塞状态。
tryAcquire()
尝试获得令牌,返回获取令牌成功或失败,不阻塞线程。
tryAcquire(long timeout, TimeUnit unit)
尝试获得令牌,在超时时间内循环尝试获取,直到尝试获取成功或超时返回,不阻塞线程。
release()
释放一个令牌,唤醒一个获取令牌不成功的阻塞线程。
3. 案例 停车场
@Slf4j
public class SemaphoreExample1 {
private static int threadCount = 6;
public static void main(String[] args) throws InterruptedException {
//创建一个可缓存的线程池
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore=new Semaphore(3);
for (int i = 0; i < threadCount; i++) {
final int threadNum = i;
executorService.execute(() -> {
try {
semaphore.acquire();//获取许可 可以获取多个 semaphore.acquire(3);
test(threadNum);
semaphore.release();//释放许可 可以释放多个
} catch (InterruptedException e) {
log.error("exception",e);
}
});
}
log.info("nwk");/*需要执行的线程*/
executorService.shutdown();
}
private static void test(int t) throws InterruptedException {
//设置随机停车时间
System.out.println(t+" 抢到了车位");
//设置随机停车时间
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(t+" ------离开了车位");
}
}
Semaphore 和countDownLatch 模拟并发
@Slf4j
public class CountExample1 {
//总数
public static int clientTotal = 5000;
//并发数
public static int threaTotal = 50;
public static int count = 0;
public static void add() {
count++;
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threaTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("count:{}", count);
}
}