java - Alternating Output Number and Letter in 2 Threads without Lock
问题描述
In an interview I was asked to use 2 and only 2 threads to print the string 1A2B3C...24X25Y26Z
, where one thread only prints numbers and the other only prints letter. I wrote the following code:
public class App {
static volatile int x = 0;
static volatile boolean numPrinted = false;
static class NumThread implements Runnable {
@Override
public void run() {
while (x < 26) {
if (!numPrinted) {
System.out.print(x + 1);
numPrinted = true;
}
}
}
}
static class LetterThread implements Runnable {
@Override
public void run() {
while (x < 26) {
if (numPrinted) {
System.out.print((char) ('A' + x));
++x;
numPrinted = false;
}
}
}
}
public static void main(String[] args) {
Thread foo = new Thread(new NumThread());
Thread bar = new Thread(new LetterThread());
foo.start();
bar.start();
try {
foo.join();
bar.join();
} catch (InterruptedException ignored) {
}
System.out.println();
}
}
In about 1 out of 10 runs, it will produce
1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z27
What's the concurrency issue with my code? I avoid AtomicInteger
intentionally.
解决方案
Both threads are busy-waiting. So this is possible:
- LetterThread prints Z
- NumThread checks if
x<26
, it is - LetterThread increments x, sets numPrinted=false
- NumThread check numPrinted, it is false, so prints 27
In NumThred check x again after numPrinted.
推荐阅读
- angular - 角度滚动到元素并打开手风琴
- linux - 有没有办法在其 shebang 中注释 bash 的编码?
- c - 调试器可以修改寄存器吗
- arrays - 如何检查通过Angular中的数组循环的文件扩展名?
- java - 在抽象类或强制转换中实现子类方法?
- html - 导航栏崩溃在引导 v5.0 中不起作用
- c - 为什么 gcc 和 clang 没有警告写入地址 0?
- ios - 即使检索了 clientSecret,Apple Pay 付款也不会通过
- python - 使用 Django 自定义用户模型成功创建超级用户后无法登录 Django 管理面板
- html - Markdown 可点击复选框