CountDownLatch和CyclicBarrier

来源:互联网 发布:java摇奖机转盘 编辑:程序博客网 时间:2024/05/16 09:20

CoutDownLatch

  • 关键函数:
    • countDown()
    • await()
  • 目的:在N个线程都执行完成时,调用latch.await()方法的线程再执行一段逻辑,否则就一直等在latch.await()的地方。
  • 用法示例:
/**  * 工人类  *  */  class Worker {      private String name;        // 名字      private long workDuration;  // 工作持续时间        /**      * 构造器      */      public Worker(String name, long workDuration) {          this.name = name;          this.workDuration = workDuration;      }        /**      * 完成工作      */      public void doWork() {          System.out.println(name + " begins to work...");          try {              Thread.sleep(workDuration); // 用休眠模拟工作执行的时间          } catch(InterruptedException ex) {              ex.printStackTrace();          }          System.out.println(name + " has finished the job...");      }  }    /**  * 测试线程  *  */  class WorkerTestThread implements Runnable {      private Worker worker;      private CountDownLatch cdLatch;        public WorkerTestThread(Worker worker, CountDownLatch cdLatch) {          this.worker = worker;          this.cdLatch = cdLatch;      }        @Override      public void run() {          worker.doWork();        // 让工人开始工作          cdLatch.countDown();    // 工作完成后倒计时次数减1      }  }    class CountDownLatchTest {        private static final int MAX_WORK_DURATION = 5000;  // 最大工作时间      private static final int MIN_WORK_DURATION = 1000;  // 最小工作时间        // 产生随机的工作时间      private static long getRandomWorkDuration(long min, long max) {          return (long) (Math.random() * (max - min) + min);      }        public static void main(String[] args) {          CountDownLatch latch = new CountDownLatch(2);   // 创建倒计时闩并指定倒计时次数为2          Worker w1 = new Worker("代码李", getRandomWorkDuration(MIN_WORK_DURATION, MAX_WORK_DURATION));          Worker w2 = new Worker("王大锤", getRandomWorkDuration(MIN_WORK_DURATION, MAX_WORK_DURATION));            new Thread(new WorkerTestThread(w1, latch)).start();          new Thread(new WorkerTestThread(w2, latch)).start();            try {              latch.await();  // 等待倒计时闩减到0              System.out.println("All jobs have been finished!");          } catch (InterruptedException e) {              e.printStackTrace();          }      }  }


CyclicBarrier

  • 关键函数:
    • 构造函数可以指定一个runnable,在N个线程都启动以后执行。
    • await()
  • 目的:让N个线程都被启动了以后,再执行一个逻辑,然后再唤醒之前所有在等待的线程。如果有一个线程没有被启动,其他所有调用await()的线程都会等待。
  • 用法示例:
public class TestCyclicBarrier {    private static final int THREAD_NUM = 5;        public static class WorkerThread implements Runnable{        CyclicBarrier barrier;                public WorkerThread(CyclicBarrier b){            this.barrier = b;        }                @Override        public void run() {            // TODO Auto-generated method stub            try{                System.out.println("Worker's waiting");                //线程在这里等待,直到所有线程都到达barrier。                barrier.await();                System.out.println("ID:"+Thread.currentThread().getId()+" Working");            }catch(Exception e){                e.printStackTrace();            }        }            }        /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {            //当所有线程到达barrier时执行            @Override            public void run() {                // TODO Auto-generated method stub                System.out.println("Inside Barrier");                            }        });                for(int i=0;i<THREAD_NUM;i++){            new Thread(new WorkerThread(cb)).start();        }    }}/*以下是输出:Worker's waitingWorker's waitingWorker's waitingWorker's waitingWorker's waitingInside BarrierID:12 WorkingID:8 WorkingID:11 WorkingID:9 WorkingID:10 Working*/


原创粉丝点击