Java runnable中的无限循环失效?
一些简化的代码来说明我的问题:Java runnable中的无限循环失效?,java,multithreading,loops,queue,runnable,Java,Multithreading,Loops,Queue,Runnable,一些简化的代码来说明我的问题: public class QueriesQueueRunnable implements Runnable { private List<String> queue = new ArrayList<String>(); @Override public void run() { while(true){ if (!this.getQueue().isEmpty()) {
public class QueriesQueueRunnable implements Runnable {
private List<String> queue = new ArrayList<String>();
@Override
public void run() {
while(true){
if (!this.getQueue().isEmpty()) {
System.out.println(this.getQueue().get(0));
this.getQueue().remove(0);
}
}
}
}
公共类QueriesQueueRunnable实现Runnable{
私有列表队列=新的ArrayList();
@凌驾
公开募捐{
while(true){
如果(!this.getQueue().isEmpty()){
System.out.println(this.getQueue().get(0));
this.getQueue().remove(0);
}
}
}
}
QueriesQueueRunnable QueriesQueueRunnable=新建QueriesQueueRunnable();
线程线程=新线程(queriesQueueRunnable).start();
对于(int i=0;i<1000;i++){
如果(i==500){
试一试{
睡眠(5000);
}捕获(中断异常例外){
Thread.currentThread().interrupt();
}
}
queryQueueRunnable.getQueue().add(String.valueOf(i));
}
输出仅在i==499迭代之前显示。为什么?这就像是执行脱离了可运行循环
Java 1.7当您的代码处于睡眠状态时,另一个线程无休止地旋转,毫无结果,这使得它容易受到JIT编译器的优化。由于该线程无法知道正在更新
queue
,因此优化器假定queue.isEmpty()
将永远返回true
,并完全跳过检查
避免此问题的一种方法是将队列
字段设置为volatile
,这会通知JVM其他线程可以同时修改该值:
private volatile List<String> queue = new ArrayList<String>();
private volatile List queue=new ArrayList();
请注意,尽管这将解决您的特定问题,但您的代码仍然远不是线程安全的,因为ArrayList
不适用于并发访问
还要注意的是,程序永远不会完成,除非您将次线程设为a。当您的代码处于睡眠状态时,另一个线程会无休止地旋转,并且毫无结果,这使得它容易受到JIT编译器的优化。由于该线程无法知道正在更新
queue
,因此优化器假定queue.isEmpty()
将永远返回true
,并完全跳过检查
避免此问题的一种方法是将队列
字段设置为volatile
,这会通知JVM其他线程可以同时修改该值:
private volatile List<String> queue = new ArrayList<String>();
private volatile List queue=new ArrayList();
请注意,尽管这将解决您的特定问题,但您的代码仍然远不是线程安全的,因为ArrayList
不适用于并发访问
还请注意,除非您将次线程设为a,否则您的程序将永远不会完成。您是否等待了整整五秒钟?是否有任何错误消息,或者它只是挂起?
Thread Thread=new Thread(queryQueueRunnable).start()代码>是一个编译错误。我已经等了五秒钟是的。没有任何错误。输出刚好在499停止。你等了整整五秒钟了吗?是否有任何错误消息,或者它只是挂起?Thread Thread=new Thread(queryQueueRunnable).start()代码>是一个编译错误。我已经等了五秒钟是的。没有任何错误。输出在499中停止。那么我应该使用Vector和synchronized使代码线程安全吗?@user2132478如果使用同步,则不需要向量,但如果使用Vector,则仍需要围绕If-Then逻辑进行同步。但是您最好使用包中的并发队列。那么我应该使用Vector和synchronized使代码线程安全吗?@user2132478如果使用同步,您不需要向量,但是如果使用Vector,您仍然需要围绕If-Then逻辑进行同步。但您最好使用包中的并发队列。