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

java并发学习之CountDownLatch

2013-12-29 00:00 603 查看
摘要: 用CountDownLatch编写健壮的并发程序。

从java se5开始,java.util.concurrent中就引入了大量设计用来解决并发问题的新类。学习使用这些新类有助于我们编写出更加简单而健壮的并发程序。

今天我们开始学习第一个类:CountDownLatch

他被用来同步一个或多个任务,强制他们等待其他任务执行完毕。

countdownlatch中有一个初始计数值,任何在countdown对象上调用await()方法的任务都将被阻塞,直到初始计数值为0.用来改变初始计数值数值的方法是countdown(),每调用一次,初始值就会减一。这个方法多调用不会引起崩溃和异常,即当调的次数大于初始计数值时,latch.getCount()得到的值都为0。

countdownlatch被设计为只触发一次,计数值不能被重置。我理解是只适用于业务逻辑可以简单地分为两个阶段的情况。比如说,A:所有政治局常委到场,B:开会. A和B的顺序是不能调的。但是A里面哪个常委先到,B里面哪项议程先说,这个都是不重要的。

下面是一个例子。

/**
* 新类库中的组件
*/
package hyf.concurrent.newLibWidget;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
* @author haoyifeng
*
*/

class TaskPortrain implements Runnable
{
private static int counter = 0;
private final int id = counter++;
private static Random rand = new Random(47);
private final CountDownLatch latch;

public TaskPortrain(CountDownLatch latch)
{
this.latch = latch;
}

@Override
public void run()
{
doWork();
latch.countDown();
}

public void doWork()
{
try
{
TimeUnit.MILLISECONDS.sleep(rand.nextInt(1000));
System.out.println("latch count is "+latch.getCount());
System.out.println(this+"completed.");
} catch (InterruptedException e)
{
e.printStackTrace();
}
}

public String toString()
{
//        return String.format("%1$-3d", id);
return id+" ";
}
}

class TaskWaiting implements Runnable
{
private static int counter = 0;
private final int id = counter++;
private final CountDownLatch latch;

public TaskWaiting(CountDownLatch latch)
{
this.latch = latch;
}

@Override
public void run()
{
try
{
latch.await();
//            latch.wait(); //notify(), notifyAll(),wait(), wait(long), wait(long, int)对应的锁是synchronized.与countdownlatch不是一个东西。
System.out.println("latch barrier passed for "+this);
} catch (InterruptedException e)
{
e.printStackTrace();
System.out.println(this+" interrupted.");
}
}

@Override
public String toString()
{
return String.format("TaskWaiting %1$-3d", id);
}

}

public class CountDownLatchTest1
{

static int SIZE = 100;

/**
* @param args
*/
public static void main(String[] args) throws Exception
{
ExecutorService exec = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(SIZE);
for(int i=0;i<10;i++)
exec.execute(new TaskWaiting(latch));
for (int i = 0; i < SIZE; i++)
//            for (int i = 0; i < SIZE+100; i++)
exec.execute(new TaskPortrain(latch));
//            new TaskPortrain(latch).run();
System.out.println("all tasks latched. ");
exec.shutdown();
{

}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  并发 java countdownlatch