CyclicBarrier
使一组线程都到达某一个点时,再一起执行。线程调用CyclicBarrier的await()方法,等待其他线程的到来,直到所有目标线程都执行了await()方法后,这些线程才可以继续往下执行,或由最后一个到达的线程执行指定任务(传入Runnable参数)。
使用举例
闪电侠、绿箭侠和超人三人相约一起去拯救世界,三人必须都到齐了才能开始打Boss,谁最后到的,谁发号施令,招呼大家开打。这里可以看到,CyclicBarrier的构造方法中传入的Runnable,是由最后执行await()的线程来执行的。
import java.util.concurrent.*;
public class CyclicBarrierTest {
static class personThread implements Runnable{
CyclicBarrier barrier;
String name;
public personThread(String name, CyclicBarrier barrier){
this.name = name;
this.barrier = barrier;
}
@Override
public void run(){
try {
Thread.sleep(2000);
System.out.println(name + " is ready! My ID is "+Thread.currentThread().getId());
barrier.await();
Thread.sleep(1000);
System.out.println(name + " is fighting!");
}catch (BrokenBarrierException exception){
exception.printStackTrace();
}catch (InterruptedException exception){
exception.printStackTrace();
}
}
}
public static void main(String[] args){
CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println("Now, let's save the world! " + Thread.currentThread().getId());
}
});
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.execute(new personThread("the Flash",barrier));
executor.execute(new personThread("the Green Arrow", barrier));
executor.execute(new personThread("the Super Man", barrier));
executor.shutdown();
}
}
/*运行结果
the Super Man is ready! My ID is 13
the Green Arrow is ready! My ID is 12
the Flash is ready! My ID is 11
Now, let's save the world! 11
the Super Man is fighting!
the Green Arrow is fighting!
the Flash is fighting!*/
CountDownLatch
直译过来就是倒计时门闩,可以让一些调用了await()方法的线程等待count个线程调用countDown()方法后,再继续执行。CountDownLatch用一次就废了,不能循环使用,而CylicBarrier可以循环使用。
使用举例
神奇女侠想出去嗨皮,但是她发现自己没带钱,于是叫了闪电侠、绿箭侠和超人出来,他们每人随意带一些钱,等他们都到了,神奇女侠就带着他们的钱嗨皮去了。
import java.util.Random;
import java.util.concurrent.*;
public class CountDownLatchTest {
static class PersonTread implements Callable<Integer>{
CountDownLatch latch;
String name;
PersonTread(String name, CountDownLatch latch){
this.name = name;
this.latch = latch;
}
@Override
public Integer call(){
try {
int money = new Random().nextInt(100);
System.out.println("I'm "+name+", I have " + money+"$.");
TimeUnit.SECONDS.sleep(2);
latch.countDown();
return money;
}catch (Exception e){
e.printStackTrace();
return 0;
}
}
}
public static void main(String[] args){
CountDownLatch latch = new CountDownLatch(3);
ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> future1 = executor.submit(new PersonTread("the Flash", latch));
Future<Integer> future2 = executor.submit(new PersonTread("the Green Arrow",latch));
Future<Integer> future3 = executor.submit(new PersonTread("the Superman",latch ));
executor.execute(new Runnable() {
@Override
public void run() {
try {
latch.await();
System.out.println("I'm eating watermelons...");
}catch (Exception e){
e.printStackTrace();
}
}
});
executor.shutdown();
try {
latch.await();
int money = future1.get() + future2.get() + future3.get();
System.out.println("I'm the Wonder Women, now I have "+money+"$ to have fun! Bye guys!");
}
catch (Exception e){
e.printStackTrace();
}
}
}
/*运行结果
I'm the Green Arrow, I have 53$.
I'm the Flash, I have 62$.
I'm the Superman, I have 88$.
I'm eating watermelons...
I'm the Wonder Women, now I have 203$ to have fun! Bye guys!
*/