我看到一篇关于多线程的帖子,使用
volatile
变量来模拟信号量来实现两个线程的交替输出。
下面的代码有线程安全问题吗?
public class Signal {
private static volatile int signal = 0;
static class ThreadA implements Runnable {
@Override
public void run() {
while (signal < 5) {
if (signal % 2 == 0) {
System.out.println("threadA: " + signal);
signal++;
}
}
}
}
static class ThreadB implements Runnable {
@Override
public void run() {
while (signal < 5) {
if (signal % 2 == 1) {
System.out.println("threadB: " + signal);
signal = signal + 1;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new ThreadA()).start();
Thread.sleep(1000);
new Thread(new ThreadB()).start();
}
}
// output example:
threadA: 0
threadB: 1
threadA: 2
threadB: 3
threadA: 4
作业? ;-) 是的,代码有问题。
signal
的递增不是原子的。所以你可以期待类似的事情有时您会看到 threadB: 5
,有时却看不到。
这可以例如导致两个线程在 while 检查中看到
signal == 4
。然后 ThreadA
运行它的“if 代码”,从而将 signal
增加到 5
。然后ThreadB
输入“if代码”并打印threadB: 5
,这可能不是代码的意图