题目链接
题目描述
我们提供了一个类:
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"。
提示:
尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。
你看到的输入格式主要是为了确保测试的全面性。
思路
1、信号量
#include <semaphore.h>
class Foo {
public:
sem_t t1,t2;
Foo() {
sem_init(&t1,0,0);
sem_init(&t2,0,0);
}
void first(function<void()> printFirst) {
printFirst();
sem_post(&t1);
}
void second(function<void()> printSecond) {
sem_wait(&t1);
printSecond();
sem_post(&t2);
}
void third(function<void()> printThird) {
sem_wait(&t2);
printThird();
}
};
2、互斥锁+条件变量
class Foo {
public:
pthread_mutex_t mutex;
pthread_cond_t cond;
int flag;
Foo() {
flag=0;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
}
void first(function<void()> printFirst) {
pthread_mutex_lock(&mutex);
printFirst();
flag=1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
void second(function<void()> printSecond) {
pthread_mutex_lock(&mutex);
while(flag!=1)
pthread_cond_wait(&cond,&mutex);
printSecond();
flag=2;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
void third(function<void()> printThird) {
pthread_mutex_lock(&mutex);
while(flag!=2)
pthread_cond_wait(&cond,&mutex);
printThird();
flag=3;
pthread_mutex_unlock(&mutex);
}
};
3、双屏障法
class Foo {
public:
pthread_barrier_t two,three;
Foo() {
pthread_barrier_init(&two,NULL,2);
pthread_barrier_init(&three,NULL,3);
}
void first(function<void()> printFirst) {
printFirst();
pthread_barrier_wait(&two);
pthread_barrier_wait(&three);
}
void second(function<void()> printSecond) {
pthread_barrier_wait(&two);
printSecond();
pthread_barrier_wait(&three);
}
void third(function<void()> printThird) {
pthread_barrier_wait(&three);
printThird();
}
};