CountDownLatch 和 CyclicBarrier 的区别
CountDownLatch:? 只能使用一次
CyclicBarrier: ?????? 可以循环使用
?
?
package com.colorcc.multi.thread.jcp;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchDemo {
??? private static CountDownLatch cdl = new CountDownLatch(3);
??? public static void main(String[] args) throws InterruptedException {
??? ??? ExecutorService executor = Executors.newFixedThreadPool(3);
??? ??? for (int i = 0; i < 3; i++) {
??? ??? ??? executor.execute(new CountDownLatchThread());
??? ??? }
??? ??? System.out.println("Main start ...");
??? ??? cdl.await();
??? ??? System.out.println("Main after ..."); // main 的语句永远比线程的晚
??? }
??? static class CountDownLatchThread implements Runnable {
??? ??? @Override
??? ??? public void run() {
??? ??? ??? System.out.println(Thread.currentThread().getName() + " start ...");
??? ??? ??? System.out.println(Thread.currentThread().getName() + " after ...");
??? ??? ??? cdl.countDown();
??? ??? ??? // cdl.countDown(); // 这里算再减一次
??? ??? }
??? }
}
?
某次执行结果:
pool-1-thread-1 start ...
pool-1-thread-1 after ...
pool-1-thread-2 start ...
pool-1-thread-2 after ...
Main start ...
pool-1-thread-3 start ...
pool-1-thread-3 after ...
Main after ...? //必然在最后
?
?
package com.colorcc.multi.thread.jcp;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierDemo {
??? /**
??? ?* @param args
??? ?*/
??? public static void main(String[] args) {
??? ??? final CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
??? ??? ??? //每次 await() 后调用此方法
??? ??? ??? @Override
??? ??? ??? public void run() {
??? ??? ??? ???
??? ??? ??? ??? System.out.println("Succeed.");
??? ??? ??? }
??? ??? });
??? ??? ExecutorService executor = Executors.newFixedThreadPool(3);
??? ??? for (int i = 0; i < 3; i++) {
??? ??? ??? executor.execute(new Runnable() {
??? ??? ??? ??? @Override
??? ??? ??? ??? public void run() {
??? ??? ??? ??? ??? System.out.println(Thread.currentThread().getName() + " before.");
//??? ??? ??? ??? ??? try {
//??? ??? ??? ??? ??? ??? Thread.sleep(200);
//??? ??? ??? ??? ??? } catch (InterruptedException e1) {
//??? ??? ??? ??? ??? ??? e1.printStackTrace();
//??? ??? ??? ??? ??? }
??? ??? ??? ??? ??? System.out.println(Thread.currentThread().getName() + " after sleep.");
??? ??? ??? ??? ??? try {
??? ??? ??? ??? ??? ??? cb.await(); //等待点1: 所有线程执行到此,等待别人都执行完成,继续向下
??? ??? ??? ??? ??? } catch (InterruptedException e) {
??? ??? ??? ??? ??? ??? e.printStackTrace();
??? ??? ??? ??? ??? } catch (BrokenBarrierException e) {
??? ??? ??? ??? ??? ??? e.printStackTrace();
??? ??? ??? ??? ??? }
??? ??? ??? ??? ??? System.out.println(Thread.currentThread().getName() + " middle.");
??? ??? ??? ??? ??? try {
??? ??? ??? ??? ??? ??? cb.await(); //等待点2: 所有线程执行到此,再次等待别人都执行完成,继续向下
??? ??? ??? ??? ??? } catch (InterruptedException e) {
??? ??? ??? ??? ??? ??? e.printStackTrace();
??? ??? ??? ??? ??? } catch (BrokenBarrierException e) {
??? ??? ??? ??? ??? ??? e.printStackTrace();
??? ??? ??? ??? ??? }
??? ??? ??? ??? ??? System.out.println(Thread.currentThread().getName() + " after.");
??? ??? ??? ??? ??? try {
??? ??? ??? ??? ??? ??? cb.await(); //等待点3: 所有线程执行到此,再次等待别人都执行完成,继续向下
??? ??? ??? ??? ??? } catch (InterruptedException e) {
??? ??? ??? ??? ??? ??? e.printStackTrace();
??? ??? ??? ??? ??? } catch (BrokenBarrierException e) {
??? ??? ??? ??? ??? ??? e.printStackTrace();
??? ??? ??? ??? ??? }
??? ??? ??? ??? ??? System.out.println(Thread.currentThread().getName() + " last.");
??? ??? ??? ??? }
??? ??? ??? });
??? ??? }
??? ???
??? ??? System.out.println("Main done.");
??? }
}
某次执行结果:
pool-1-thread-1 before.?? //可以无序
pool-1-thread-2 before.
pool-1-thread-2 after sleep.
pool-1-thread-3 before.
pool-1-thread-3 after sleep.
Main done.
pool-1-thread-1 after sleep.
Succeed.
pool-1-thread-1 middle.?? //等待点1后
pool-1-thread-2 middle.
pool-1-thread-3 middle.
Succeed.
pool-1-thread-3 after. //等待点2后
pool-1-thread-2 after.
pool-1-thread-1 after.
Succeed.
pool-1-thread-1 last. //等待点3后
pool-1-thread-3 last.
pool-1-thread-2 last.
?
?