我们提供了一个类:
public class Foo { public void one() { print("one"); } public void two() { print("two"); } public void three() { print("three"); } }
三个不同的线程将会共用一个 Foo
实例。
one()
方法two()
方法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"。
注意:
尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。
你看到的输入格式主要是为了确保测试的全面性。
C++
class ZeroEvenOdd {
private:
int n;
mutex Mu;
condition_variable cv1;
condition_variable cv2;
condition_variable cv3;
int counter=1;
public:
ZeroEvenOdd(int n)
{
this->n = n;
}
// printNumber(x) outputs "x", where x is an integer.
void zero(function printNumber)
{
for(int i=1;i<=n;i++)
{
std::unique_lock lck(Mu);
cv1.wait(lck,[this](){return counter==1;});
printNumber(0);
if(i%2==1)
{
counter=3;
cv3.notify_one();
}
else
{
counter=2;
cv2.notify_one();
}
}
}
void even(function printNumber)
{
for(int i=2;i<=n;i+=2)
{
std::unique_lock lck(Mu);
cv2.wait(lck,[this](){return counter==2;});
printNumber(i);
counter=1;
cv1.notify_one();
}
}
void odd(function printNumber)
{
for(int i=1;i<=n;i+=2)
{
std::unique_lock lck(Mu);
cv3.wait(lck,[this](){return counter==3;});
printNumber(i);
counter=1;
cv1.notify_one();
}
}
};