java - 为什么这段代码会陷入死循环
问题描述
我正在使用jdk1.8。
这段代码直接运行到一个无限循环中,但是如果我添加注释代码,它会正常运行。我试过很多代码,只要涉及到加锁的操作,都可以正常运行。
public class StateTest {
public static void main(String[] args) {
State state = new State();
new Thread(new Work(state)).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
state.setStart(true);
System.out.println("the main thread is finished");
}
static class State {
private boolean isStart = false;
public boolean isStart() {
return this.isStart;
}
public void setStart(boolean start) {
this.isStart = start;
}
}
static class Work implements Runnable {
private State state;
public Work(State state) {
this.state = state;
}
@Override
public void run() {
int i = 0;
//endless loop
while (!this.state.isStart()) {
i++;
// if open this code,it will be ok
// synchronized (this) {
//
// }
}
System.out.println(String.format("work start run after %s loops", i));
}
}
}
解决方案
问题是State
实例不是线程安全的。如果一个线程调用setStart
并且第二个线程调用isStart
,那么第二个线程可能看不到第一个设置为1的值。
您正在使用setStart
一个State
实例,以便一个实例可以向第二个实例发出信号以结束循环。如果第二个线程没有看到状态变化(由于上述原因),则循环不会终止2。
解决方案:
- 改变
setStart
和isStart
成为synchronized
方法。 isStart
将字段声明为volatile
。- 不要编写自己的
State
类,而是使用标准java.util.concurrent
类来进行同步;例如CountDownLatch
(javadoc)。
我建议您花时间学习 Oracle Java 并发教程课程:
1 - Java 语言规范的“Java 内存模型”部分中列出了为什么会发生这种情况的技术解释。但是,JLS 不是以初学者可以理解的方式编写的,这部分特别困难。
2 - 事实上,JLS 并没有说明是否会看到更改。实际行为可能取决于程序员无法控制的一系列因素。
推荐阅读
- pandas - 在熊猫中添加带有前缀的唯一标识符列
- python - How to calculate a column using the most common words calculated from another dataframe in Python?
- powershell - coloredlogs not displaying "correctly" in windows powershell
- angular - Angular: Difference in runtime with Providers in AppModule and providedIn: 'root'?
- next.js - what is the best way to deploy nextjs app very first time and after than when a re-deployment is required?
- python - install dtaidistance -> Exception: The compiled dtaidistance C library is not available
- python - How to take Different multi line inputs?
- excel - 如何正确处理错误 91 对象变量或未设置块变量
- html - How do I display an html string in swift with WebKit?
- python - 将 csv 数据转换为特定格式的嵌套 json