Multi-Programming-6 CountDown latches

1. 什么是倒计数栓?What is CountDownLatch in java?

倒计数锁是什么,有什么用,点击这里将得到关于该问题的详细信息。

CountDownLatch in Java is a type of synchronizer which allows one
Thread to wait for one or more Threads before it starts processing.

CountDownLatch works on latch principle, thread will wait until gate
is open. One thread waits for n number of threads specified while
creating CountDownLatch.

e.g. final CountDownLatch latch = new CountDownLatch(3);

Here we set the counter to 3.

Any thread, usually main thread of application, which calls
CountDownLatch.await() will wait until count reaches zero or it’s
interrupted by another Thread. All other threads are required to do
count down by calling CountDownLatch.countDown() once they are
completed or ready to the job. as soon as count reaches zero, the
Thread awaiting starts running.

Here the count is get decremented by CountDownLatch.countDown()
method.

The Thread which calls the await() method will wait until the initial
count reaches to zero.

To make count zero other threads need to call the countDown() method.
Once the count become zero the thread which invoked the await() method
will resume (start its execution).

The disadvantage of CountDownLatch is that it’s not reusable: once the
count become zero it is no longer usable.

总结一下:
1). CountDownLatch 是 Java语言中的一种同步机制,可以保证一个线程的执行在一个或多个线程执行完成后开始。
2). 作用原理:如其命名,CountDownLatch “倒计数栓”–线程会等一直等待直到栓所对应的门打开为止。
3). CountDownLatch 的一个缺点:它是不可重用的,一旦倒数到0则该栓对象不再可用。

2. CountDownLatch 如何使用?How is it used?

CountDownLatch latch = new CountDownLatch(3);   
latch.countDown();//每次线程执行完后,latch值减1.       
latch.await();//等待latch的值变为0.


一般调用latch.await()的线程(一般是主线程)将会一直等待,直到latch数量为0,或被中断。

3. CountDownLatch 应用实例

下面例子选取了三个为CountDownLatch约束的Task,如果设置得当的CountDownLatch数目,则主线程会在latch数量将为0之后运行,保证了线程的执行顺序。

package com.fqyuan._4countdown;

import java.util.concurrent.CountDownLatch;

public class TaskOneWithLatch implements Runnable {
    private CountDownLatch latch;

    public TaskOneWithLatch(CountDownLatch latch) {
        this.latch = latch;
    }

    private void process() {
        System.out.println("Task 1 Start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        latch.countDown();
        System.out.println("Task 1 Finish");
    }

    @Override
    public void run() {
        process();
    }

}
package com.fqyuan._4countdown;

import java.util.concurrent.CountDownLatch;

public class TaskTwoWithLatch implements Runnable {
    private CountDownLatch latch;

    public TaskTwoWithLatch(CountDownLatch latch) {
        this.latch = latch;
    }

    private void process() {
        System.out.println("Task 2 Start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        latch.countDown();
        System.out.println("Task 2 Finish");
    }

    @Override
    public void run() {
        process();
    }
}
package com.fqyuan._4countdown;

import java.util.concurrent.CountDownLatch;

public class TaskThreeWithLatch implements Runnable {
    private CountDownLatch latch;

    public TaskThreeWithLatch(CountDownLatch latch) {
        this.latch = latch;
    }

    private void process() {
        System.out.println("Task 3 Start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        latch.countDown();
        System.out.println("Task 3 Finish");
    }

    @Override
    public void run() {
        process();
    }
}
package com.fqyuan._4countdown;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDown {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        ExecutorService executor = Executors.newFixedThreadPool(3);
        // If changed to value less than 3, then main thread may start executing
        // along with the executing thread.
        CountDownLatch latch = new CountDownLatch(2);
        executor.submit(new TaskOneWithLatch(latch));
        executor.submit(new TaskTwoWithLatch(latch));
        executor.submit(new TaskThreeWithLatch(latch));
        try {
            // Cause current thread to wait until latch has counted to zero or
            // interrupted.
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("Total time used is: " + (end - start));
    }

}
//Running results:
Task 1 Start
Task 2 Start
Task 3 Start
Task 3 Finish
Task 1 Finish
Total time used is: 1009
Task 2 Finish

You may download code at my github.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值