LeetCode_1114_按序打印

题目

我们提供了一个类:

public class Foo {
  public void one() { print("one"); }
  public void two() { print("two"); }
  public void three() { print("three"); }
}
三个不同的线程将会共用一个 Foo 实例。

线程 A 将会调用 one() 方法
线程 B 将会调用 two() 方法
线程 C 将会调用 three() 方法
请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。

 

示例 1:

输入: [1,2,3]
输出: "onetwothree"
解释:
有三个线程会被异步启动。
输入 [1,2,3] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 two() 方法,线程 C 将会调用 three() 方法。
正确的输出是 "onetwothree"。
示例 2:

输入: [1,3,2]
输出: "onetwothree"
解释:
输入 [1,3,2] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 three() 方法,线程 C 将会调用 two() 方法。
正确的输出是 "onetwothree"。
 

注意:

尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。

你看到的输入格式主要是为了确保测试的全面性。

 

 

分析:本题可采用构建执行屏障的方法来解答,可采用jdk1.5 引入CountDownLatch 解决,其实现原理如下:

  • CountDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
  • 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

 

解答:

class Foo {

private CountDownLatch countDownLatchA;

private CountDownLatch countDownLatchB;

public Foo() {
countDownLatchA = new CountDownLatch(1);
countDownLatchB = new CountDownLatch(1);
}

public void first(Runnable printFirst) throws InterruptedException {

printFirst.run();
countDownLatchA.countDown();

}

public void second(Runnable printSecond) throws InterruptedException {
countDownLatchA.await();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
countDownLatchB.countDown();
}

public void third(Runnable printThird) throws InterruptedException {
countDownLatchB.await();
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}

 

posted @ 2019-10-18 14:08  freeair16  阅读(157)  评论(0)    收藏  举报