CountDownLatch--控制三个线程执行顺序(三)

来源:互联网 发布:免费双轨制软件 编辑:程序博客网 时间:2024/06/03 18:51

前言

线程中run方法调用CountDownLatch。CountDownLatch的两个核心方法:

  • countObj.countDown() 表示countObj计数减少。
  • countObj.await() 表示检查countObj若不为0则阻塞,为0,则允许执行。

比较

join

join的工作原理是(源码),不停检查thread是否存活,如果存活则让当前线程永远wait,直到thread线程终止,线程的this.notifyAll 就会被调用。

CountDownLatch

检查计数器是否为0,如果不为0则让当前线程永远wait,直到thread线程中的计数器为0,线程的this.notifyAll 就会被调用。

方式1: 用join实现三个线程有序执行

public static void main(String[] args) {     final Thread t1=new Thread(new Runnable(){                @Override        public void run() {              System.out.println("t1");                 }   });  final Thread t2 = new Thread(new Runnable() {             @Override        public void run() {            try{                t1.join();            }catch(InterruptedException e){            }            System.out.println("t2");        }  });  final Thread t3=new Thread(new Runnable(){    @Override    public void run() {        try {            t2.join();        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("t3");    }  });  t1.start();  t2.start();  t3.start();}   

方式2: 用CountDownLatch实现三个线程有序执行

创建线程类的时候,将上一个计数器和本线程计数器传入。运行前业务执行上一个计数器.await,执行后本计数器.countDown。

public class CountLatchDown3 {    public static void main(String[] args) {            CountDownLatch c0 = new CountDownLatch(0); //①        CountDownLatch c1 = new CountDownLatch(1); //②        CountDownLatch c2 = new CountDownLatch(1); //③        Thread t1 = new Thread(new Work(c0, c1));        //c0为0,t1可以执行。t1的计数器减1        Thread t2 = new Thread(new Work(c1, c2));        //t1的计数器为0时,t2才能执行。t2的计数器c2减1        Thread t3 = new Thread(new Work(c2, c2));        //t2的计数器c2为0时,t3才能执行        t2.start();        t1.start();        t3.start();    }    //定义Work线程类,需要传入开始和结束的CountDownLatch参数    static class Work implements Runnable {        CountDownLatch c1;        CountDownLatch c2;        Work(CountDownLatch c1, CountDownLatch c2){            super();            this.c1=c1;            this.c2=c2;        }        public void run() {            try {                c1.await();//前一线程为0才可以执行                System.out.println("开始执行线程:"+ Thread.currentThread().getName());                c2.countDown();//本线程计数器减少            } catch (InterruptedException e) {                          }          }    }}

效果:

开始执行线程:Thread-0开始执行线程:Thread-1开始执行线程:Thread-2

注:将上述代码①②③处全部写CountDownLatch(0),则不会造成线程阻塞。会有如下随机结果:

开始执行线程:Thread-1开始执行线程:Thread-0开始执行线程:Thread-2
原创粉丝点击