九又四分之三站台

0%

并发工具类CountDownLatch和CyclicBarrier

CountDownLatch

CountDownLatch允许一个或多个线程等待其它线程操作完成,比如登录后返回结果前要获取用户头像用户昵称就可以分开进行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

public class CountDownLatchTest {

private static CountDownLatch countDownLatch = new CountDownLatch(2);

public static void main(String[] args) throws InterruptedException {

new Thread(() -> {
System.out.println(1);
countDownLatch.countDown();
System.out.println(2);
countDownLatch.countDown();
}).start();

countDownLatch.await();

System.out.println(3);
}
}

countDown的构造器接收一个int参数作为计数器,想等N个点完成就传入N,CountDownLatch的countDown方法会使计数器减1。上面这段代码, System.out.println(3)语句一定是最后执行的, CountDownLatch的await方法会阻塞当前线程,直到N变为0为止

CyclicBarrier

CyclicBarrier的作用是让一组线程达到屏障时(也可以叫同步点)被阻塞,直到最后一个线程达到屏障时,屏障被打开,所以被屏障阻塞的线程运行

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

public class CyclicBarrierTest {

private static CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
// private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);

public static void main(String[] args) {

new Thread(() -> {
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}

System.out.println(1);
}).start();


try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}

System.out.println(2);
}
}

上面代码主线程和子线程会永远等待,因为没有第三个线程执行await方法,即没有第三个线程达到屏障,需要把cyclicBarrier构造器参数变成2才行

CountDownLatch和CyclicBarrier的区别是CountDownLatch计数器只能使用一次,CyclicBarrier的计数器可以用reset()方法重置