1.CountDownLatch
CountDownLatch允许一个或多个线程等待其他的线程完成操作。
例子:
public class Test6 {
private final static int COUNT = 100;
public static void main(String[] args) throws Exception {
final CountDownLatch countDownLatch = new CountDownLatch(COUNT);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < COUNT; i++) {
final int a = i;
executorService.execute(() -> {
try {
getStr(a);
} catch (Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
}
countDownLatch.await();
System.out.println("Finished");
executorService.shutdown();
}
private static void getStr(int i) {
System.out.println(i);
}
}
当然可以计时等待:
使用join也可以实现相识的功能,只是这个CountDownLatch很强大。
2.Semaphore
信号量是用来控制同时访问特定资源的线程数量,他通过协调各个线程,以保证合理的使用公共资源
提供同步的机制来控制线程访问的个数
public class Test6 {
private final static int COUNT = 100;
public static void main(String[] args) throws Exception {
final Semaphore semaphore = new Semaphore(20);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < COUNT; i++) {
final int a = i;
executorService.execute(() -> {
try {
semaphore.acquire(); //获得许可
getStr(a);
semaphore.release();//释放许可
} catch (Exception e) {
e.printStackTrace();
}
});
}
System.out.println("Finished");
executorService.shutdown();
}
private static void getStr(int i) {
System.out.println(i);
}
}
semaphore.tryAcquire()尝试获取许可,如果拿不到就丢弃这个线程
3.CyclicBarrier
CyclicBarrier可以用于多线程计算数据,最后合并计算结果的场景。多个线程相互等待的场景,CyclicBarrier可以重置,而CountDownLatch不可以重置。
public class Test7 {
static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
public static void main(String[] args) throws Exception{
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
final int a = i;
executorService.execute(() -> {
try {
getStr(a);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
private static void getStr(int i) throws Exception {
System.out.println(Thread.currentThread().getName() + ":" + i);
cyclicBarrier.await();
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
等待的线程为5个,然后等满足了就继续往后执行。