您的位置:首页 > 编程语言 > Java开发

Java多线程之1-- CountDownLatch的用法

2017-02-16 12:42 405 查看
CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行,从而控制线程整体执行进度。与之对应的则是CyclicBarrier类。是等待到达某个公共屏障点后一起执行。具体看代码:

package thread;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class CountDownLatchDemo { 
        final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
      
        public static void main(String[] args) throws InterruptedException {  
            Worker worker = null;  
            ExecutorService excutorService = null;
            try{
                List<String> names = Arrays.asList("张三", "李四", "王五", "牛六", "孙七");  
                // 此处用来控制同组线程的CountDownLatch,注意构造方法里面的参数必须和生成线程的总数相等  
                CountDownLatch latch = new CountDownLatch(names.size());// 两个工人的协作  
                // 线程执行器
                excutorService = Executors.newCachedThreadPool();
                // 线程名  
                String name = null;  
                for (int i = 0; i < names.size(); i++) {  
                    name = names.get(i);  
                    // 线程初始化  
                    worker = new Worker(name,  latch);  
                    excutorService.execute(worker);
                    // 错开每条线程的执行时间
                    TimeUnit.SECONDS.sleep(i);
                }  
                // 等待所有工人完成工作  
                latch.await();  
                System.out.println("all work done at " + sdf.format(new Date()));  
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                if(excutorService != null) {
                    excutorService.shutdown();
                }
            }
        }  
      
        static class Worker implements Runnable {  
            String workerName;  
            int workTime;  
            CountDownLatch latch;  
            // 线程休眠时间  
            Random random;  
            public Worker(String workerName, CountDownLatch latch) {  
                this.workerName = workerName;
                this.latch = latch;  
                random = new Random();
            }  
      
            public void run() {  
                System.out.println("**** " + workerName + "  begin at " + sdf.format(new Date()));  
                // 工作了  
                doWork();
                System.out.println("---- " + workerName + "  end at " + sdf.format(new Date()));
                // 完成工作,计数器减一  
                latch.countDown();
                
            }  
      
            private void doWork() {  
                try {  
                    TimeUnit.SECONDS.sleep(random.nextInt(10));
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        }      
   
}


最后查看结果,你会发现,5个线程的开始时间和结束时间都是不一致的,照原来的线程调用方法,主线程在for循环完毕后就执行“========== finish for at...” 的那句打印,紧接着应该就是打印“all work done...” 的话,但是此处并没有这样,是因为latch.await()会等待所有线程执行完毕后才继续往下执行,因此你也就看到了“all work done at ”这句话在最后才执行。具体请看下图:

**** 张三  begin at 2017-02-23 17:52:43
**** 李四  begin at 2017-02-23 17:52:43
---- 张三  end at 2017-02-23 17:52:43
**** 王五  begin at 2017-02-23 17:52:44
---- 王五  end at 2017-02-23 17:52:44
---- 李四  end at 2017-02-23 17:52:45
**** 牛六  begin at 2017-02-23 17:52:46
**** 孙七  begin at 2017-02-23 17:52:49
========== finish for at 2017-02-23 17:52:53
---- 牛六  end at 2017-02-23 17:52:54
---- 孙七  end at 2017-02-23 17:52:55
all work done at 2017-02-23 17:52:55
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 多线程