java并发之同步辅助类CountDownLatch

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java并发之同步辅助类CountDownLatch相关的知识,希望对你有一定的参考价值。

CountDownLatch

含义:

CountDownLatch可以理解为一个计数器在初始化时设置初始值,当一个线程需要等待某些操作先完成时,需要调用await()方法。这个方法让线程进入休眠状态直到等待的所有线程都执行完成。每调用一次countDown()方法内部计数器减1,直到计数器为0时唤醒。这个可以理解为特殊的CyclicBarrier。线程同步点比较特殊,为内部计数器值为0时开始。

方法:
核心方法两个:countDown()和await()
countDown():使CountDownLatch维护的内部计数器减1,每个被等待的线程完成的时候调用
await():线程在执行到CountDownLatch的时候会将此线程置于休眠

例子
开会的例子:会议室里等与会人员到齐了会议才能开始。

import java.util.concurrent.CountDownLatch;

public class VideoConference implements Runnable {
private final CountDownLatch controller;

public VideoConference(int number) {
    controller = new CountDownLatch(number);
}

public void arrive(String name) {
    System.out.printf("%s has arrived.\n", name);

    controller.countDown();// 调用countDown()方法,使内部计数器减1
    System.out.printf("VideoConference: Waiting for %d participants.\n", controller.getCount());
}

@Override
public void run() {
    System.out.printf("VideoConference: Initialization: %d participants.\n", controller.getCount());
    try {

        controller.await();// 等待,直到CoutDownLatch计数器为0

        System.out.printf("VideoConference: All the participants have come\n");
        System.out.printf("VideoConference: Let‘s start...\n");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}

参加会议人员类

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class PrintQueue {
//信号量
private Semaphore semaphore;

//是否空闲打印机
private boolean freePrinters[];

private Lock lockPrinters;

public PrintQueue(){
    //初始化三个信号
    semaphore=new Semaphore(3);
    //三台空闲打印机
    freePrinters=new boolean[3];
    for (int i=0; i<3; i++){
        freePrinters[i]=true;
    }
    lockPrinters=new ReentrantLock();
}

public void printJob (Object document){
    try {
        //获取信号量
        semaphore.acquire();

        int assignedPrinter=getPrinter();

        Long duration=(long)(Math.random()*10);
        System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n",Thread.currentThread().getName(),assignedPrinter,duration);
        TimeUnit.SECONDS.sleep(duration);

        freePrinters[assignedPrinter]=true;
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        // Free the semaphore
        semaphore.release();            
    }
}
private int getPrinter() {
    int ret=-1;

    try {
        lockPrinters.lock();
        for (int i=0; i<freePrinters.length; i++) {
            if (freePrinters[i]){
                ret=i;
                freePrinters[i]=false;
                break;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lockPrinters.unlock();
    }
    return ret;
}

}

测试类:

public class CountDownLatchMain {

public static void main(String[] args) {
    VideoConference conference = new VideoConference(10);
    Thread threadConference = new Thread(conference);
    threadConference.start();// 开启await()方法,在内部计数器为0之前线程处于等待状态
    for (int i = 0; i < 10; i++) {
        Participant p = new Participant(conference, "Participant " + i);
        Thread t = new Thread(p);
        t.start();
    }
}

}

海量视频
技术分享图片

以上是关于java并发之同步辅助类CountDownLatch的主要内容,如果未能解决你的问题,请参考以下文章

java并发之同步辅助类CyclicBarrier

java并发之同步辅助类CountDownLatch

Java并发编程的4个同步辅助类(CountDownLatchCyclicBarrierSemphorePhaser)

并发编程-AQS同步组件之CountDownLatch 闭锁

多线程必看之JAVA线程并发辅助类

Java并发和高并发学习总结- J.U.C之工具类