代码演示
CountDownLautch
// 等待线程数量
int size = 10;
// 倒计时数量
int count = 2;
Thread[] waitThreads = new Thread[size];
Thread decrThread;
CountDownLatch countDownLatch = new CountDownLatch(count);
Runnable r = () -> {
try {
System.out.println(Thread.currentThread().getName() + "开始等待");
// 调用 await(),会让线程等待
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "等待完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < size; i++) {
waitThreads[i] = new Thread(r);
}
decrThread = new Thread(() -> {
for (; countDownLatch.getCount() != 0; ) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// count 减一操作
countDownLatch.countDown();
}
}
});
// 线程开始等待
for (int i = 0; i < size; i++) {
waitThreads[i].start();
}
// 减 count 线程启动
decrThread.start();
TimeUnit.SECONDS.sleep(10);
Thread-0开始等待
Thread-3开始等待
Thread-2开始等待
Thread-1开始等待
Thread-4开始等待
Thread-5开始等待
Thread-6开始等待
Thread-7开始等待
Thread-8开始等待
Thread-9开始等待
Thread-3等待完毕
Thread-5等待完毕
Thread-6等待完毕
Thread-8等待完毕
Thread-9等待完毕
Thread-4等待完毕
Thread-1等待完毕
Thread-2等待完毕
Thread-0等待完毕
Thread-7等待完毕
Semaphore
ExecutorService service = Executors.newFixedThreadPool(10);
// 指定信号量数量
int count = 5;
Semaphore semaphore = new Semaphore(count);
Runnable runnable = () -> {
try {
System.out.println(Thread.currentThread().getName() + " 尝试获取许可证");
// 尝试获取许可证,拿不到会 blocking
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " start working");
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 绝对要归还许可证
semaphore.release();
System.out.println(Thread.currentThread().getName() + " 归还许可证");
}
};
for (int i = 0; i < 10; i++) {
service.submit(runnable);
}
service.shutdown();
while (!service.isTerminated());
pool-1-thread-2 尝试获取许可证
pool-1-thread-2 start working
pool-1-thread-1 尝试获取许可证
pool-1-thread-1 start working
pool-1-thread-3 尝试获取许可证
pool-1-thread-3 start working
pool-1-thread-4 尝试获取许可证
pool-1-thread-4 start working
pool-1-thread-4 归还许可证
pool-1-thread-5 尝试获取许可证
pool-1-thread-5 start working
pool-1-thread-6 尝试获取许可证
pool-1-thread-6 start working
pool-1-thread-6 归还许可证
pool-1-thread-7 尝试获取许可证
pool-1-thread-7 start working
pool-1-thread-8 尝试获取许可证
pool-1-thread-9 尝试获取许可证
pool-1-thread-10 尝试获取许可证
pool-1-thread-8 start working
pool-1-thread-2 归还许可证
pool-1-thread-9 start working
pool-1-thread-8 归还许可证
pool-1-thread-1 归还许可证
pool-1-thread-10 start working
pool-1-thread-10 归还许可证
pool-1-thread-3 归还许可证
pool-1-thread-5 归还许可证
pool-1-thread-7 归还许可证
pool-1-thread-9 归还许可证
第一层密码:CKNB 第二层密码:HRLM