多线程进阶---Thread.join()/CountDownLatch.await() /CyclicBarrier.await()

Thread.join()

CountDownLatch.await() 

CyclicBarrier.await()

三者都是用来控制程序的“流动” 可以让程序“堵塞”在某几个点 以利用经由多线程操作后的某些最终结果

eg1:

 1 public class joinTest {
 2 
 3     private static Thread[] ts = new Thread[10];
 4     private static AtomicInteger ai = new AtomicInteger(0);
 5 
 6     public joinTest() {
 7         for (int i = 0; i < 10; i++) {
 8             ts[i] = new Thread() {
 9                 @Override
10                 public void run() {
11                     try {
12                         Thread.sleep(100);
13                     }catch (Exception e){
14 
15                     }
16                     ai.incrementAndGet();
17                 }
18             };
19         }
20     }
21 
22    
23 
24 
25     public static void main(String[] args) throws Exception  {
26 
27         new joinTest();
28 
29         for (int i = 0; i < 10; i++) {
30             ts[i].start();
31         }
32 
33         for (int i = 0; i < 10; i++) {
34             ts[i].join();
35         }
36 
37         System.out.println(ai);
38 
39     }
40 
41 }

  

此时输出为10 

注意在run方法中的sleep操作,此时必须写到try/catch代码块内,因为异常不能跨线程传播 所以不能写在方法尾部throws!

 

eg2:

public class controlThread {
    private static final int ThreadCount = 500;
    private static AtomicInteger result = new AtomicInteger(0);
    private static CountDownLatch endCount = new CountDownLatch(ThreadCount);

    static void helper(){
for(int i=0;i<500;i++){ new Thread() { @Override public void run() { result.incrementAndGet(); endCount.countDown(); } }.start(); } } public static void main(String[] args) throws Exception{
new Thread(){ @Override public void run(){ helper(); } }.start(); endCount.await(); //Thread.sleep(10); print(result); } }

此时result结果为500

如果注释掉await()  加上sleep  则数值随机  

全都注释掉一般情况为0

eg3:

public class cyclicBarrierTest {
    private static CyclicBarrier cyclic = new CyclicBarrier(5,new BarrierRun());
    private static boolean flag = false;
    static class BarrierRun implements Runnable{
        @Override
        public void run(){
            if(!flag)
            print("we five are ready!");
            else
                print("we five are ready again!");
        }
    }

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 5; i++) {
            new Thread() {
                @Override
                public void run() {

                    try {
                        print(Thread.currentThread()+"'s worker has comed");
                        cyclic.await();
                        flag = true ;
                        print(Thread.currentThread()+"wait you five so long!");
                        cyclic.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }.start();
        }

    }

}

 

只有当指定数目的线程进入到cyclic.await()方法处,才会让各个线程继续执行。 而且该方法可以复用。

这里如果某一个线程被中断,其他程序将不会愚蠢的等待 人到齐了 再执行接下来的任务 此时程序报错

 

posted @ 2017-06-15 15:32  丨核桃牛奶  阅读(907)  评论(0编辑  收藏  举报