看看这个博客 更有助于理解闭锁
CountDownLatch:闭锁
一个线程等待多个线程执行完。才继续自己的操作;可以使用闭锁来保证某些活动到其他活动做完才继续进行
应用
1. 确保计算机在其需要的所有资源被初始化之后才继续执行;
2. 确保某个服务在其依赖的所有其他服务都已经启动之后才启动;
3. 等待直到某个操作所有参与者都准备就绪了继续操作。
demo1
package com.mark.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** * author:Mark * date:2018/7/31 17:46 */
@Slf4j
public class CountDownLatchTest1 {
private final static int threadCount = 20;
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
final CountDownLatch countDownLatch = new CountDownLatch(threadCount);//闭锁
for (int i = 0; i < threadCount; i++) {
final int threadNum = i;
executorService.execute(()->{
try {
test(threadNum);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
countDownLatch.countDown();
}
});
}
countDownLatch.await();
log.info("finish");
executorService.shutdown();
}
private static void test(int threadNum) throws InterruptedException {
Thread.sleep(100);
log.info("{}", threadNum);
Thread.sleep(100);
}
}
运行结果
22:56:26.945 [pool-1-thread-19] INFO com.mark.example.aqs.CountDownLatchTest1 – 18
22:56:26.945 [pool-1-thread-8] INFO com.mark.example.aqs.CountDownLatchTest1 – 7
22:56:26.945 [pool-1-thread-12] INFO com.mark.example.aqs.CountDownLatchTest1 – 11
22:56:26.945 [pool-1-thread-9] INFO com.mark.example.aqs.CountDownLatchTest1 – 8
22:56:26.945 [pool-1-thread-15] INFO com.mark.example.aqs.CountDownLatchTest1 – 14
22:56:26.945 [pool-1-thread-13] INFO com.mark.example.aqs.CountDownLatchTest1 – 12
22:56:26.946 [pool-1-thread-1] INFO com.mark.example.aqs.CountDownLatchTest1 – 0
22:56:26.945 [pool-1-thread-10] INFO com.mark.example.aqs.CountDownLatchTest1 – 9
22:56:26.945 [pool-1-thread-18] INFO com.mark.example.aqs.CountDownLatchTest1 – 17
22:56:26.945 [pool-1-thread-11] INFO com.mark.example.aqs.CountDownLatchTest1 – 10
22:56:26.946 [pool-1-thread-3] INFO com.mark.example.aqs.CountDownLatchTest1 – 2
22:56:26.946 [pool-1-thread-17] INFO com.mark.example.aqs.CountDownLatchTest1 – 16
22:56:26.945 [pool-1-thread-2] INFO com.mark.example.aqs.CountDownLatchTest1 – 1
22:56:26.946 [pool-1-thread-20] INFO com.mark.example.aqs.CountDownLatchTest1 – 19
22:56:26.945 [pool-1-thread-14] INFO com.mark.example.aqs.CountDownLatchTest1 – 13
22:56:26.945 [pool-1-thread-7] INFO com.mark.example.aqs.CountDownLatchTest1 – 6
22:56:26.946 [pool-1-thread-6] INFO com.mark.example.aqs.CountDownLatchTest1 – 5
22:56:26.946 [pool-1-thread-16] INFO com.mark.example.aqs.CountDownLatchTest1 – 15
22:56:26.946 [pool-1-thread-4] INFO com.mark.example.aqs.CountDownLatchTest1 – 3
22:56:26.946 [pool-1-thread-5] INFO com.mark.example.aqs.CountDownLatchTest1 – 4
22:56:27.051 [main] INFO com.mark.example.aqs.CountDownLatchTest1 – finish
运行结果分析:程序中声明了一个大小为20的CountDownLatch实例,在线程池中运行20个线程的时候。等到这20个线程全部执行完后再执行log.info("finish");
demo2
package com.mark.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/** * author:Mark * date:2018/7/31 17:46 */
@Slf4j
public class CountDownLatchTest2 {
private final static int threadCount = 10;
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
final CountDownLatch countDownLatch = new CountDownLatch(threadCount);//闭锁
for (int i = 0; i < threadCount; i++) {
final int threadNum = i;
executorService.execute(()->{
try {
test(threadNum);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
countDownLatch.countDown();
}
});
}
countDownLatch.await(20, TimeUnit.MILLISECONDS);//指定时间唤醒--》注意打印finish语句
log.info("finish");
executorService.shutdown();//不会立即停止线程池里的线程。而是等待线程池里的线程执行完再关闭线程池
}
private static void test(int threadNum) throws InterruptedException {
Thread.sleep(10);
log.info("{}", threadNum);
}
}
运行结果:
23:01:28.254 [pool-1-thread-1] INFO com.mark.example.aqs.CountDownLatchTest2 – 0
23:01:28.254 [pool-1-thread-3] INFO com.mark.example.aqs.CountDownLatchTest2 – 2
23:01:28.254 [pool-1-thread-2] INFO com.mark.example.aqs.CountDownLatchTest2 – 1
23:01:28.263 [main] INFO com.mark.example.aqs.CountDownLatchTest2 – finish
23:01:28.269 [pool-1-thread-3] INFO com.mark.example.aqs.CountDownLatchTest2 – 4
23:01:28.269 [pool-1-thread-2] INFO com.mark.example.aqs.CountDownLatchTest2 – 5
23:01:28.269 [pool-1-thread-1] INFO com.mark.example.aqs.CountDownLatchTest2 – 3
23:01:28.280 [pool-1-thread-3] INFO com.mark.example.aqs.CountDownLatchTest2 – 6
23:01:28.280 [pool-1-thread-1] INFO com.mark.example.aqs.CountDownLatchTest2 – 8
23:01:28.280 [pool-1-thread-2] INFO com.mark.example.aqs.CountDownLatchTest2 – 7
23:01:28.291 [pool-1-thread-3] INFO com.mark.example.aqs.CountDownLatchTest2 – 9