【并发编程】- CountDownLatch 同步

91 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

调用Exchanger的运行类代码如下:

public class ExchangerRun {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<>();
        GetThread getThread = new GetThread(exchanger);
        new Thread(getThread).start();
        System.out.println("main结束!");
    }
}

运行结果如下:

Connected to the target VM, address: '127.0.0.1:58438', transport: 'socket'
main结束!
java.util.concurrent.TimeoutException
	at java.util.concurrent.Exchanger.exchange(Exchanger.java:626)
	at com.ozx.concurrentprogram.semaphore.entity.GetThread.run(GetThread.java:24)
	at java.lang.Thread.run(Thread.java:748)

当调用exchange(V x,long timeout,TimeUnit unit)方法后在指定时间内没有其他线程获取数据,则出现超时异常。

Exchanger是线程件传输数据的方式之一,而且在传输的数据类型上并没有任何限制。

CountDownLatch

当CountDownLatch的计数不为0时,线程呈阻塞状态。

使用CountDownLatch实现线程"组团"方式执行任务

public class CountDownLatchService {
    private CountDownLatch countDownLatch = new CountDownLatch(1);

    volatile private Integer i = 1;

    public void runMethod(){
        try {
            System.out.println("第一个 i:"+i);
            i++;
            countDownLatch.await();
            System.out.println("第二个 i:"+i);
            System.out.println("继续往下执行...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void downMethod(){
        System.out.println("第三个 i:"+i);
        i++;
        countDownLatch.countDown();
    }
}

创建ThreadA代码如下:

public class ThreadA implements Runnable{
    private CountDownLatchService service;

    public ThreadA(CountDownLatchService service){
        this.service=service;
    }


    @Override
    public void run() {
        service.runMethod();
    }
}

运行类代码如下:

public class CountDownLatchRun {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatchService service = new CountDownLatchService();
        ThreadA threadA = new ThreadA(service);
        new Thread(threadA).start();
        Thread.sleep(2000);
        service.downMethod();
    }
}

运行结果如下:

第一个 i:1
第三个 i:2
第二个 i:3
继续往下执行...

​ CountDownLatch提供的功能是判断count计数不为0时,则当前线程呈wait状态,在同步点处等待。new CountDownLatch(1)的作用是创建1个计数的CountDownLatch类的对象,当线程执行countDownLatch.await()代码时是等待装填,程序不往下继续运行,程序执行countDownLatch.countDown()代码时计数由1变成0,之前呈等待状态的线程向下运行。

​ CountDownLatch也是一个同步功能的辅助类,使用效果是给定一个计数,当使用这个CountDownLatch类的线程判断计数不为0时,则呈wait状态,如果为0则继续运行。