java并发学习之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)