0%

java | CountdownLatch 简介

用来进行线程间同步写作,等待所有线程完成倒计时。

  • await()
    • 等待计数归零
  • countDown()
    • 让计数减一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.chat;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;

@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(3);

new Thread(() ->{
log.debug("begin...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
log.debug("end...");
}).start();
new Thread(() ->{
log.debug("begin...");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
log.debug("end...");
}).start();
new Thread(() ->{
log.debug("begin...");
try {
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
log.debug("end...");
}).start();
log.debug("wait...");
countDownLatch.await();
log.debug("wait end...");
}
}

输出

1
2
3
4
5
6
7
8
23:02:46.900 [main] DEBUG com.chat.Test - wait...
23:02:46.900 [Thread-0] DEBUG com.chat.Test - begin...
23:02:46.900 [Thread-2] DEBUG com.chat.Test - begin...
23:02:46.900 [Thread-1] DEBUG com.chat.Test - begin...
23:02:46.904 [Thread-0] DEBUG com.chat.Test - end...
23:02:46.905 [Thread-1] DEBUG com.chat.Test - end...
23:02:46.906 [Thread-2] DEBUG com.chat.Test - end...
23:02:46.907 [main] DEBUG com.chat.Test - wait end...

为什么要用 CountdownLatch 不用 join

这是因为 CountdownLatch 是更高级的用法,用起来简单,好懂。并且,如果用的是线程池而不是多进程,就必须要用 CountdownLatch 达到 join 效果。

线程池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.chat;

import lombok.extern.slf4j.Slf4j;

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

@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(3);
ExecutorService executorService = Executors.newFixedThreadPool(4);

executorService.submit(() -> {
log.debug("begin...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
log.debug("end...");
});

executorService.submit(() -> {
log.debug("begin...");
try {
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
log.debug("end...");
});

executorService.submit(() -> {
log.debug("begin...");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
log.debug("end...");
});

executorService.submit(() -> {
log.debug("wait...");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("wait end...");
});
}


}

3 个线程池中的线程计算,一个等待。

请我喝杯咖啡吧~