控制线程顺序执行

         前段时间面试被问了一个问题:

         “ABC三个线程,如何让AB并发执行完了再顺序执行C?”

        “额,不好意思,不清楚唉,我自己回家等通知吧 = =”

         再一次感慨过去写过的代码,业务场景不复杂,都没有很多对线程的操作,印象中使用过的就是Thread.sleep(),更不用说多线程了……唉,需要学习的东西还有很多啊,好好学习,天天向上~

        以下两种实现方式文字部分摘抄整理自:日积月累:Java等待子线程执行完毕,再执行后续逻辑


1. Join

        Thread提供了 join() 让一个线程等待另一个线程完成的方法。当在某个程序执行流程中调用其它线程的join()方法时,调用线程将被阻塞,知道被join()方法加入的join线程执行完毕为止,在继续运行。

        join()方法的实现原理是不停检查join线程是否存活,如果join线程存活则让当前线程永远等待。直到join线程完成后,线程的this.notifyAll()方法会被调用。

        代码如下:

public class Test1 {
  public static void main (String[] args) {
    Thread t1 = new Thread(new TestThread(), "threadA");
    Thread t2 = new Thread(new TestThread(), "threadB");
    t1.start();
    t2.start();
    try {
       t1.join(); // 主线程等待A线程执行完
       t2.join(); // 主线程等待B线程执行完
    } catch (InterruptedException  e) {
      e.printStackTrace();
    }
    
    // 然后就可以愉快的执行C线程啦~
    new Thread(new TestThread(), "threadC");
  }
}

class TestThread implements Runnable {
  @Override
  public void run() {
    for (int i = 0 ; i < 5; i++) {
      System.out.println(Thread.currentThread().getName() + " am running: " + i);
    }
  }
}

2. CountDownLatch

        CountDownLatch允许一个或多个线程等待其他线程完成操作。CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N。当我们调用countDown方法时,N就会减1,await方法会阻塞当前线程,直到N变成0。

         这里说的N个点,可以使用N个线程,也可以是1个线程里的N个执行步骤。

/**
 * Created by chenhuogu on 2018/7/24.
 */
public class Test1 {
  public static void main (String[] args) {
    CountDownLatch countDownLatch = new CountDownLatch(2);
    Thread t1 = new Thread(new TestThread(countDownLatch), "threadA");
    Thread t2 = new Thread(new TestThread(countDownLatch), "threadB");
    t1.start();
    t2.start();
    try {
      countDownLatch.await(); // await方法阻塞当前主线程,直到countDownLatch计数器为0,即线程全部执行完
    } catch (InterruptedException  e) {
      e.printStackTrace();
    }

    // 然后就可以愉快的执行C线程啦~~~

  }
}

class TestThread implements Runnable {
  private CountDownLatch countDownLatch;
  public TestThread (CountDownLatch countDownLatch) {
    this.countDownLatch = countDownLatch;
  }
  @Override
  public void run() {
    for (int i = 0 ; i < 5; i++) {
      System.out.println(Thread.currentThread().getName() + " am running: " + i);
    }
    countDownLatch.countDown();
  }
}

猜你喜欢

转载自blog.csdn.net/lvdou1120101985/article/details/81181470