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.