并发工具类
- CountDownLacth
- Semaphore
- CyclicBarrier
CountDownLacth
CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有框架服务之后执行。
public class CountDownLatchExample {
private final static int threadCount = 200;
public static void main(String[] arg) {
ExecutorService exec = Executors.newCachedThreadPool();
final CountDownLatch lacth = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
exec.execute( () -> {
final int threadNum = i;
try {
test(threadNum);
} catch (Exception e) {
log.error("exception", e);
} finally {
// latch递减
lacth.countDown();
}
});
}
// 等待latch计数器为0,则继续往下执行
latch.await();
// latch的await方法也可以传入等待时间,等到等待时间后不管有没完成计数都往下执行
// latch.await( 10, TimeUnit.MILLISECONDS);
log.info("finished");
exec.shutdown();
}
public static void test(int i) throw Exception{
log.info("thread: {}", i);
}
}
Semaphore
主要用来控制并发访问特定资源的线程数量,协调各个线程合理使用公共资源。
public class SemaphoreExample {
private final static int threadCount = 200;
public static void main(String[] arg) {
ExecutorService exec = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < threadCount; i++) {
exec.excute( () )-> {
final int threadNum = i;
try {
// tryAcquire会尝试去获取一个信号量,如果获取不到
// 则什么都不会发生,走接下来的逻辑
// if (semaphore.tryAcquire(1)) {
// test(i);
// semaphore.release();//释放一个信号量
// }
semaphore.acquire();//获取一个信号量
test(i);
semaphore.release();//释放一个信号量
} catch (Exception e) {
log.error("exception", e);
}
});
}
log.info("finished");
exec.shutdown();
}
public static void test(int i) throw Exception{
log.info("thread: {}", i);
}
}
CyclicBarrier
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。
public class CyclicBarrierExample {
private final static int threadCount = 200;
private final static CyclicBarrier cyclicBarrier = new CyclicBarrier(7,
() -> {
log.info("callback is running !");
}
);
public static void main(String[] arg) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < threadCount; i++) {
exec.excute( () -> {
final int threadNum = i;
try {
race(i);
} catch (Exception e) {
log.error("exception", e);
}
});
}
log.info("finished");
exec.shutdown();
}
public static void race(int i) throw Exception{
log.info("thread {} is ready", i);
cyclicBarrier.await();
log.info("thread {} is continue", i);
}
}