LeetCode1114. 按序打印[多线程] 6种解法
Posted 折纸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode1114. 按序打印[多线程] 6种解法相关的知识,希望对你有一定的参考价值。
作者:折纸
个人博客:https://www.zhezhi.press
记录菜鸡的成长之旅!
题目描述
我们提供了一个类:
public class Foo {
public void first() { print("first"); }
public void second() { print("second"); }
public void third() { print("third"); }
}
三个不同的线程 A、B、C 将会共用一个Foo
实例。
- 一个将会调用
first()
方法 - 一个将会调用
second()
方法 - 还有一个将会调用
third()
方法
请设计修改程序,以确保second()
方法在first()
方法之后被执行,third()
方法在second()
方法之后被执行。
示例 1:
输入: [1,2,3]
输出: "firstsecondthird"
解释:
有三个线程会被异步启动。
输入 [1,2,3] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 second() 方法,线程 C 将会调用 third() 方法。
正确的输出是 "firstsecondthird"。
示例 2:
输入: [1,3,2]
输出: "firstsecondthird"
解释:
输入 [1,3,2] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 third() 方法,线程 C 将会调用 second() 方法。
正确的输出是 "firstsecondthird"。
提示:
- 尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。
- 你看到的输入格式主要是为了确保测试的全面性。
话不多说 直接上代码,简单复习一下Lock、synchronized、还有CountDownLatch、Semaphore、CyclicBarrier等工具类的使用
ReentrantLock + Condition
class Foo {
ReentrantLock lock = new ReentrantLock();
Condition a = lock.newCondition();
Condition b = lock.newCondition();
Condition c = lock.newCondition();
private volatile int status = 1;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
try{
lock.lock();
while(status!=1){
a.await();
}
status = 2;
printFirst.run();
b.signal();
}finally{
lock.unlock();
}
// printFirst.run() outputs "first". Do not change or remove this line.
}
public void second(Runnable printSecond) throws InterruptedException {
try{
lock.lock();
while(status!=2){
b.await();
}
status = 3;
printSecond.run();
c.signal();
}finally{
lock.unlock();
}
// printSecond.run() outputs "second". Do not change or remove this line.
}
public void third(Runnable printThird) throws InterruptedException {
try{
lock.lock();
while(status!=3){
c.await();
}
status = 1;
printThird.run();
a.signal();
}finally{
lock.unlock();
}
// printThird.run() outputs "third". Do not change or remove this line.
}
}
LockSupport
class Foo {
static Thread aThread = null,bThread = null,cThread = null;
private volatile int status = 1;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
aThread = Thread.currentThread();
printFirst.run();
status = 2;
LockSupport.unpark(bThread);
// printFirst.run() outputs "first". Do not change or remove this line.
// printFirst.run();
}
public void second(Runnable printSecond) throws InterruptedException {
bThread = Thread.currentThread();
while(status!=2)
LockSupport.park();
printSecond.run();
status = 3;
LockSupport.unpark(cThread);
// printSecond.run() outputs "second". Do not change or remove this line.
// printSecond.run();
}
public void third(Runnable printThird) throws InterruptedException {
cThread = Thread.currentThread();
while(status!=3)
LockSupport.park();
printThird.run();
status = 1;
LockSupport.unpark(aThread);
// printThird.run() outputs "third". Do not change or remove this line.
// printThird.run();
}
}
synchronized + wait/notify
class Foo {
Object lock = new Object();
private volatile int status = 1;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
synchronized(lock){
while(status!=1){
lock.wait();
}
printFirst.run();
status = 2;
lock.notifyAll();
}
// printFirst.run() outputs "first". Do not change or remove this line.
}
public void second(Runnable printSecond) throws InterruptedException {
synchronized(lock){
while(status!=2){
lock.wait();
}
printSecond.run();
status = 3;
lock.notifyAll();
}
// printSecond.run() outputs "second". Do not change or remove this line.
}
public void third(Runnable printThird) throws InterruptedException {
synchronized(lock){
while(status!=3){
lock.wait();
}
printThird.run();
status = 1;
lock.notifyAll();
}
// printThird.run() outputs "third". Do not change or remove this line.
}
}
Semaphore
class Foo {
Semaphore s = new Semaphore(1);
private volatile int status = 1;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
while(status!=1){
}
s.acquire();
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
status = 2;
s.release();
}
public void second(Runnable printSecond) throws InterruptedException {
while(status!=2){
}
s.acquire();
// printFirst.run() outputs "first". Do not change or remove this line.
printSecond.run();
status = 3;
s.release();
// printSecond.run() outputs "second". Do not change or remove this line.
}
public void third(Runnable printThird) throws InterruptedException {
while(status!=3){
}
s.acquire();
// printFirst.run() outputs "first". Do not change or remove this line.
printThird.run();
status = 1;
s.release();
// printThird.run() outputs "third". Do not change or remove this line.
}
}
CountDownLatch
class Foo {
CountDownLatch aLatch = new CountDownLatch(1);
CountDownLatch bLatch = new CountDownLatch(1);
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
aLatch.countDown();
}
public void second(Runnable printSecond) throws InterruptedException {
aLatch.await();//aLatch计数器为1,当线程1打印完毕后--为0,这里不再被阻塞 线程2开始打印
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
bLatch.countDown();
}
public void third(Runnable printThird) throws InterruptedException {
bLatch.await();//bLatch计数器为1,当线程1打印完毕后--为0,这里不再被阻塞 线程2开始打印
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
CyclicBarrier
class Foo {
CyclicBarrier cy1 = new CyclicBarrier(2);
CyclicBarrier cy2 = new CyclicBarrier(2);
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
try{
cy1.await();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
}
public void second(Runnable printSecond) throws InterruptedException {
try{
cy1.await(); //线程1已经通过了cy1表示线程1已经打印完毕
//当线程1 和2都到达此处后 线程2才开始打印
printSecond.run();
cy2.await();//线程2到达屏障2
}catch(BrokenBarrierException e){
e.printStackTrace();
}
// printSecond.run() outputs "second". Do not change or remove this line.
}
public void third(Runnable printThird) throws InterruptedException {
try{
cy2.await();//线程2打印完毕后线程3才开始打印
printThird.run();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
// printThird.run() outputs "third". Do not change or remove this line.
}
}
以上是关于LeetCode1114. 按序打印[多线程] 6种解法的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口