这是一个面试问题,任何帮助将不胜感激
你如何同步两个线程,其中一个增加一个值,另一个显示它(P.S.显示该值的线程必须只在它是一个新值时才显示一个值)
例如:int x = 5;
T1
: 增加到 6T2
: 必须显示 6(只显示一次),当它变成 7 时必须再次显示
我回答说我会使用类似以下的信号量:
int c=0; // variable that I used to synchronize
// In T1
if( c = 0 )
{
c++;
x++; // value that is incremented
}
// in T2
if( c == 1 )
{
cout<<x;
c--;
}
然后他问如果在将 c 设置为 1 之后但在增加 x 之前有从线程
T1
到 T2
的上下文切换,你会怎么做(因为在这种情况下它会在增加 x 之前进入 P2 )这部分我答不上来。任何帮助,将不胜感激。
最佳答案
不错的运动。
您尚未在问题中指定 c++
标签,但问题本身包含 cout<<x
,因此您可能正在面试 C++ 职位。尽管如此,我还是会用 Java 来回答,因为这是一个面试问题,只要我避免使用任何对 Java 太特定的东西,语言就不会有太大影响。
正如你的面试官所指出的,同步必须在两个方向发生:
所以我们需要一些东西让我们知道打印机已经完成(这样增量器可以运行),另一个让我们知道增量器已经完成。我为此使用了两个信号量:
Working version on Ideone
import java.util.concurrent.Semaphore;
class IncrementDemo {
static int x = 0;
public static void main(String[] args) {
Semaphore incrementLock = new Semaphore(0);
Semaphore printLock = new Semaphore(0);
Thread incrementer = new Thread(() -> {
for(;;) {
incrementLock.acquire(); //Wait to be allowed to increment
x++;
printLock.release(); //Allow the printer to print
}
});
Thread printer = new Thread(() -> {
for (;;) {
incrementLock.release(); //Let the incrementer to its job
printLock.acquire(); //Wait to be allowed to print
System.out.println(x);
}
});
incrementer.setDaemon(false); //Keep the program alive after main() exits
printer.setDaemon(false);
incrementer.start(); //Start both threads
printer.start();
}
}
(为了便于阅读,我删除了
acquire
周围的 try/catch 块)。输出:
1
2
3
4
5
6
7
...
关于java - 使用信号量的线程同步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48793791/