您的位置:首页 > 编程语言 > Java开发

Java多线程——6 并发流程控制CountDownLatch、CycliBarrier

2013-08-19 23:22 531 查看
对于程序中的多线程并发控制,总是有些繁琐,比如,如何让多个线程处于等待状态,又可以有条不紊的运行,或者如何让多个线程如同集会一样开始工作。但作为Java程序员,我们应该感到庆幸,因为java为我们提供一些类,使得原本可能无从下手的问题变得简单,同时也大大的提高了开发的效率。介绍一下允许对多个线程计时使得运行有序的CountDownLatch、CycliBarrier

先看一下CountDownLatch几个方法

CountDownLatch(int count)

void await() 让当前对象处于等待状态

boolean await(long timeout, TimeUnit unit) 使线程在给定时间内等待,知道此对象count为0

void countDown()使count减一,为零开始执行当前线程

getCount()获得count值

计数无法被重置,只能使用一次,需要时要重新定义。

应用场合:需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。
这个时候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。

看一下下面例子

//五个人吃大餐,吃完了付款
public class TestCountDownLatch
{
public static void main(String[] args) throws InterruptedException
{

final CountDownLatch start = new CountDownLatch(1);
final CountDownLatch end = new CountDownLatch(5);

//开启一个线程池
ExecutorService exc =  Executors.newFixedThreadPool(5);

for(int i=0; i<5; i++)
{
final int no = i+1;

Runnable run = new Runnable()
{

@SuppressWarnings("static-access")
@Override
public void run()
{
try
{
Thread.currentThread().sleep((long)(Math.random()*10000));
start.await();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
System.out.println("第"+no+"个人吃完了");

end.countDown();
}
}
};

exc.submit(run);
}
System.out.println("大餐开始了!");
start.countDown();

//直到count为0时,才开始执行
end.await();
System.out.println("所有人都吃饱了,可以付款了");

}
}

运行结果:

大餐开始了!

第5个人吃完了

第2个人吃完了

第3个人吃完了

第4个人吃完了

第1个人吃完了

所有人都吃饱了,可以付款了

在介绍一下CycliBarrier

它是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier
很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的
barrier。

同时,CyclicBarrier允许多次重复使用

下面,看一个CycliBarrier的例子

//下面是一个模拟以百米比赛
public class TestCycliBarrier
{

public static void main(String[] args)
{
CyclicBarrier barrier = new CyclicBarrier(5);

System.out.println("现在进行一百米比赛");

// 初始化一个线程池
ExecutorService es = Executors.newFixedThreadPool(5);
es.submit(new MyRunnable("第1个人", barrier));
es.submit(new MyRunnable("第2个人", barrier));
es.submit(new MyRunnable("第3个人", barrier));
es.submit(new MyRunnable("第4个人", barrier));
es.submit(new MyRunnable("第5个人", barrier));

}
}

class MyRunnable implements Runnable
{
// 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点
private CyclicBarrier barrier;

private String name;

public MyRunnable(String name, CyclicBarrier barrier)
{
this.name = name;
this.barrier = barrier;
}

@Override
public void run()
{
try
{
Thread.sleep(1000 * (new Random()).nextInt(8));
System.out.println(name + "准备好了");
// 调用barrier的await方法,在所有参与者都已经到此 barrier之前,将一直阻塞等待。
barrier.await();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "起跑");
}
}

运行结果:

现在进行一百米比赛

第4个人准备好了

第2个人准备好了

第5个人准备好了

第1个人准备好了

第3个人准备好了

第3个人起跑

第4个人起跑

第5个人起跑

第2个人起跑

第1个人起跑
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 多线程 线程