java并发(四)CountDownLatch闭锁

来源:互联网 发布:2016中超球员数据 编辑:程序博客网 时间:2024/05/12 02:47

CountDownLatch

  1. Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器
    的性能。
  2. CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作
    之前,它允许一个或多个线程一直等待。
  3. 闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活
    动直到其他活动都完成才继续执行:
    • 确保某个计算在其需要的所有资源都被初始化之后才继续执行;
    • 确保某个服务在其依赖的所有其他服务都已经启动之后才启动;
    • 等待直到某个操作所有参与者都准备就绪再继续执行。

类似join和yield方法

举例说明

创建一个类实现Runnable接口在run方法中打印100以内的偶数,在主方法中测试该run方法执行时间

class LatchDemo implements Runnable{    @Override    public void run() {            for(int i=0;i<100;i++){                if(i%2==0){                    System.out.println(i);                }            }        }}

主函数测试方法:

    public static void main(String[] args) {        LatchDemo ld = new LatchDemo();        long start = System.currentTimeMillis();        for(int i=0;i<5;i++){            new Thread(ld).start();        }        long end = System.currentTimeMillis();        System.out.println("spend time:"+(end-start));//spend time:1008    }

输出结果:

spend time:1000...

结果并不像我们所预想的那样,并没有计算出执行了多长时间,

原因分析

创建了10个子线程之的循环结束之后,主线程继续执行,主线程打印时间后结束,但是子线程还在运行。所以导致我们看到的结果。

解决方式

原因分析完毕,我们想在子线程全部执行完之后再继续执行主线程,这个时候打印的时间就有事子线程真正执行他的时间。

使用CountDownLatch闭锁

class LatchDemo implements Runnable{    private CountDownLatch latch;    public LatchDemo(CountDownLatch latch){        this.latch = latch;    }    @Override    public void run() {        // 加上 catch 和 finally,在后这种保证方法必须被执行        try {            for(int i=0;i<100;i++){                try {                    Thread.sleep(10);                } catch (InterruptedException e) {                    e.printStackTrace();                }                if(i%2==0){                    System.out.println(i);                }            }        } finally {            latch.countDown();//相当于--,每次执行此方法就减1技计数        }    }}

测试主方法:

public static void main(String[] args) {        // 要控制 5 个线程,所以传入的是 5        CountDownLatch latch = new CountDownLatch(5);        LatchDemo ld = new LatchDemo(latch);//        LatchDemo ld = new LatchDemo();        long start = System.currentTimeMillis();        for(int i=0;i<5;i++){            new Thread(ld).start();        }        try {            latch.await();//主线程让出cpu执行权,释放对象锁,子线程全部执行完然后继续执行        } catch (InterruptedException e) {            e.printStackTrace();        }        long end = System.currentTimeMillis();        System.out.println("spend time:"+(end-start));//spend time:1008    }

结果输出:

...989898spend time:1009

可见打印输出了执行时间

1 0
原创粉丝点击