Java CountDownLatch 学习总结

来源包

同为 java.util.concurrent 下的,即也是并发多线程相关下的类,直译 “倒计时锁存器”,一般用于多线程场景,单一的线程也可以,用于等待多个任务完成后再执行其他操作;

提供方法

await()

导致当前线程等待,直到锁存器倒数到零,除非该线程是{@linkplain Thread35;interrupt interrupted}即被打断状态。
如果当前计数为零,则此方法立即返回。
如果当前计数大于零,则当前线程将出于线程调度目的被禁用,并处于休眠状态,直到发生以下两种情况之一:
由于调用{@link#countDown}方法,计数达到零;或者其他线程{@linkplain thread#中断}当前线程。
如果当前线程:
在进入此方法时设置了其中断状态;或者
在等待时{@linkplain Thread#interrupt interrupted},
则抛出{@link InterruptedException},并清除当前线程的中断状态。

简单说就是当使用了这个方法后当前这一个线程将进入等待状态,直到计数器被减到0或者当前线程被中断,计数器被减到0后,所有等待的线程将被唤醒继续向下执行

await(long timeout, TimeUnit unit)

同上,但是指定了等待的超时时间,即线程除了上方两种被唤醒的情况下,等待到超时时间后也会被唤醒

countDown()

当前计数器减一,如果如果减到 0 则唤醒所有等待在这个 CountDownLatch 上的线程。

getCount()

获取当前计数的数值

业务书写示例

将需要一会儿处理的业务 list 设置为计数器的大小,
然后对里面的业务数据执行异步操作,处理业务过程中不论是否有异常都需要对计数器减一,最终使用 await 等待所有任务执行完成,执行完成后,将进入后续处理

            final CountDownLatch latch = new CountDownLatch(lists.size());
            
            for (List<JSONObject> item: lists) {
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        // ....... 业务处理
                        } catch (Exception e) {
                            // 异常处理
                        } finally {
                            latch.countDown();
                        }
                    }
                });
            }

            try {
                latch.await();
            } catch (InterruptedException e) {
                log.error("线程被中断", e);
            }

       // lists 处理完成后的其他业务操作

一般代码示例

public static void main(String[] args) throws InterruptedException {
        final CountDownLatch downLatch = new CountDownLatch(3);

        Await wait111 = new Await("wait111", downLatch);
        Await wait222 = new Await("wait222", downLatch);
        CountDownStart countDownStart = new CountDownStart(downLatch);

        wait111.start();
        wait222.start();
        Thread.sleep(1000);
        countDownStart.run();

    }


class Await extends Thread{

    private CountDownLatch countDownLatch;
    private String name;

    public Await(String name, CountDownLatch countDownLatch){
        this.name = name;
        this.countDownLatch = countDownLatch;
    }


    @Override
    public void run() {
        System.out.println(name + " start.....");
        System.out.println(name + " run.....");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name + " continue.....run");
    }
}

class CountDownStart extends Thread{

    private CountDownLatch countDownLatch;

    public CountDownStart(CountDownLatch countDownLatch){
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        countDownLatch.countDown();
        countDownLatch.countDown();
        countDownLatch.countDown();
        System.out.println("start countDown");
    }
}

运行结果:

wait222 start.....
wait222 run.....
wait111 start.....
wait111 run.....
start countDown
wait111 continue.....run
wait222 continue.....run

但是当我把线程等待去除后:

    public static void main(String[] args) throws InterruptedException {
        final CountDownLatch downLatch = new CountDownLatch(3);

        Await wait111 = new Await("wait111", downLatch);
        Await wait222 = new Await("wait222", downLatch);
        CountDownStart countDownStart = new CountDownStart(downLatch);

        wait111.start();
        wait222.start();
//        Thread.sleep(1000);
        countDownStart.run();

    }

结果:

start countDown
wait111 start.....
wait111 run.....
wait111 continue.....run
wait222 start.....
wait222 run.....
wait222 continue.....run

另外两个线程线程并没有开始就执行,可能被抢占了,也可能调度优先度不同,实际使用时还是需要多多实验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值