Java 并发编程之闭锁

Java 并发编程之闭锁

1. 什么是闭锁

闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态。

2. 闭锁的作用

闭锁相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程通过,当到达结束状态时,这扇门会打开并允许所有线程通过。

简单说,就是确保多线程或单线程的工作完成后,才能执行之后的操作。

3. Java 的闭锁实现 CountDownLatch

它可以使一个或多个状态等待一组事件发生。闭锁状态包括一个计数器,该计数器被初始化为一个正整数,表示需要等待的事件数量。 countDown方法用来递减计数器,表示有一个事件已经发生了, await方法会阻塞的一直等待计数器达到0,或者等待中的线程中断或者等待超时。

4. 实际应用

4.1 在计时测试中使用

在这里TestHarness创建一定数量线程,执行并发任务。使用两个闭锁,起始门,和结束门。起始门确保所有线程启动, 结束们确保所有线程执行完成。

public class TestHarness {
    public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
        final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(nThreads);

        for (int i = 0; i < nThreads; i++) {
            Thread t = new Thread() {
                @Override
                public void run() {
                    try {
                        startGate.await();
                        try {
                            task.run();
                        } finally {
                            endGate.countDown();
                        }
                    } catch (InterruptedException e) {
                    }

                }
            };
            t.start();
        }
        long start = System.nanoTime();
        startGate.countDown();
        endGate.await();
        long end = System.nanoTime();
        return end - start;
    }

}
4.2 模拟Shell脚本打包合并项目

我们可能有多个项目A,B,C 需要打包安装,等全部完成后才能打包合并的项目merge-all, 这时,A,B,C 可以多线程自行打包,都完成后再打包merge-all, 以下是SHELL 脚本实现,可以简单理解为 & 为开启线程, wait为闭锁门。

function package(){

    cd $sourceCodePath_A
    mvn clean install -Pagg &

    cd $sourceCodePath_B
    mvn clean install -Pagg &

    cd $sourceCodePath_C
    mvn clean install -Pagg &

    wait

    cd $sourceCodePath_all
    mvn clean package -P"$env"

}

用java模拟就是如下:

public class PackageLatchTest {

    private static final CountDownLatch gate = new CountDownLatch(3);

    public static void packageA() {
        System.out.println("compile and package A");

    }

    public static void packageB() {

        System.out.println("compile and packge B");
    }

    public static void packageC() {
        System.out.println("compile and package C");
    }

    public static void mergeAll() {
        System.out.println("merge A B C !");
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                packageA();
                gate.countDown();
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                packageB();
                gate.countDown();
            }
        });
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                packageC();
                gate.countDown();
            }
        });
        t1.start();
        t2.start();
        t3.start();

        gate.await();
        mergeAll();

    }

}
4.3 三人到餐厅一起吃饭

这个问题就是三个人相当于3个线程,各自到达指定的餐厅,然后人到齐,开始吃饭。
具体实现 请看这个:Java 并发专题 :闭锁 CountDownLatch 之一家人一起吃个饭

5. 总结

闭锁就可简单理解为, 某项任务 可多线程执行,但是汇总需要都执行完成, 在这个地方加一个闭锁,全部完成后在执行汇总.


参考
1. Java 并发编程实战 5.5.1 闭锁
2. Java 并发专题 :闭锁 CountDownLatch 之一家人一起吃个饭 http://blog.csdn.net/lmj623565791/article/details/26626391

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值