目录
一、题目概述:
【1】题目原型:
注:红色的是要求
【2】原题连结
1114. 按序打印 - 力扣(LeetCode) (leetcode-cn.com)
二、解题思路:
守先比较容易想到的是使用wait()和notifyAll()方法,此时需要再加入一个计数器,用来控制唤醒的顺序。
注:wait()方法可以将当前线程挂起,直到唤醒。notifyAll()方法可以唤醒等待的线程。
代码如下:
class Foo {
public Foo() {
}
int count = 0;
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
count ++;
notifyAll();
}
public void second(Runnable printSecond) throws InterruptedException {
while(count != 2){
wait();
}
// printSecond.run() outputs "second". Do not change or remove this line.
count++;
notifyAll();
printSecond.run();
}
public void third(Runnable printThird) throws InterruptedException {
while(count != 3){
wait();
}
// printThird.run() outputs "third". Do not change or remove this line.
count++;
notifyAll();
printThird.run();
}
}
但是由于时间限制,此方案无法ac。通过题解换一种思路:引入Semaphore工具类——信号量:它可以控制同时访问资源的线程个数。
eg.公园厕所有5个坑,10个人想要上厕所就只有5个人能使用只有其中5个人任意一个人离开后其他人才可以进去一个人,依次这样进行下去,直到10个人全部都上完厕所。
Semphore计数信号量由-个指定数量的“许可” 初始化。每调用一次acquire(),一个许可会被调用线程取走。每调用一次release(),一个许可会被返还给信号量。因此,在没有任何release()调用时,最多有N个线程能够通过acquire()方法, N是该信号量初始化时的许可的指定数量。这些许可只是一个简单的计数器。
三、题解代码:
class Foo {
public Foo() {
}
private Semaphore s2 = new Semaphore(0);
private Semaphore s3 = new Semaphore(0);
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
s2.release();
}
public void second(Runnable printSecond) throws InterruptedException {
s2.acquire();
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
s3.release();
}
public void third(Runnable printThird) throws InterruptedException {
s3.acquire();
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}