java多线程学习(一) 之 CountDownLatch和CyclicBarrier

CountDownlatch和CyclicBarrier是java并发包java.util.concurrent里的两个线程辅助类,学习这两个辅助类,可以认识到两个多线程的使用场景。

java.util.concurrent.CountDownLatch

官方的解释是很明确的:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
一个同步辅助,是为了允许一个或者多个线程在其它前提操作完成之后,继续往下执行。
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown method,

after which all waiting threads are released and any subsequent invocations of await return immediately

一个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
public static void main(String[] args) 
      throws InterruptedException
{
    final CountDownLatch latch = new CountDownLatch(5);
 
    for (int i = 0; i < 2; i++)
    {
        final int threadId = i;
        new Thread()
        {
            public void run()
            {
                System.err.println(threadId + "线程等待...");
                try
                {
                    latch.await();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                System.err.println(threadId + "线程结束...");
            };
        }.start();
    }
    Thread.sleep(1000);
    for (int i = 0; i < 5; i++)
    {
        final int threadId = i;
        new Thread()
        {
            public void run()
            {
                System.err.println("前提线程" + threadId + "完成");
                latch.countDown();
            };
        }.start();
    }
}

运行结果:

0线程等待…
1线程等待…
前提线程0完成
前提线程1完成
前提线程2完成
前提线程3完成
前提线程4完成
0线程结束…
1线程结束…
你会发现,有两个线程必须等其它四个线程完成之后才继续进行。

java.util.concurrent.CyclicBarrier
官方的解释是很明确的:

A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs

involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting

threads are released.

一个同步辅助,是为了允许多个线程在一个障碍(Barrier)点上互相等待,当大家都达到这个障碍的时候,才继续往下执行。为什么叫重复障碍(Cyclic Barrier)呢?因为当所有的

线程都到达这个点之后,还可以再重复使用它。

实例:

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
public static void main(String[] args)
{
 final CyclicBarrier barrier = new CyclicBarrier(3);
 
 for (int i = 0; i < 3; i++)
 {
    final int threadId = i;
    new Thread()
    {
       public void run()
       {
            while (true)
            {
              System.err.println(threadId + "线程到达障碍点...");
              try
              {
                  barrier.await();
                  System.err.println(threadId + "线程跨过障碍点...");
                  Thread.sleep(1000);
              }
              catch (Exception e)
              {
                  e.printStackTrace();
              }
           }
       }
    }.start();
  }
}

0线程到达障碍点…
2线程到达障碍点…
1线程到达障碍点…
1线程跨过障碍点…
2线程跨过障碍点…
0线程跨过障碍点…
1线程到达障碍点…
0线程到达障碍点…
2线程到达障碍点…
2线程跨过障碍点…
0线程跨过障碍点…
1线程跨过障碍点…

你会发现三个线程到达障碍点(barrier.await())的时候,都会阻塞在哪里,当所有线程都到达那个障碍点的时候,大家再一起跨越那个障碍点。

留言

提示:你的email不会被公布,欢迎留言^_^

*

验证码 *