[英]Why does one iteration of my arraylist work, while the other does not?
( TLDR:为什么while循环无限重复,for-loop总是有效? )
我正在编写一个Android
应用程序,并且有一个需要运行的Runnable
队列,然后从这个队列中删除:
List<Runnable> queue = new ArrayList<Runnable>();
我想以最佳方式做到这一点,并考虑以下算法:
synchronized(queue)
{
while(queue.size() > 0)
{
queue.remove(0).run();
}
}
这导致了错误,所以我不得不在循环之前添加这个检查: if (queue.size() > 0)
(真的有必要吗?)。 然而,现在,这似乎陷入无限循环。 我不得不改变我的循环,这很好用:
synchronized(queue)
{
for (int i = 0; i < queue.size(); i++)
{
queue.get(i).run();
}
queue.clear();
}
我的问题是 - 这些循环之间的低级差异是什么? 为什么while循环失败?
实际上我不能提到while循环片段冻结的原因。 一个明显的区别是,在第一种情况下,while循环中的条件取决于正文中发生的情况。 我的意思是这条线
queue.remove(0).run()
应该减少队列的大小,如果没有,循环将不会结束。 在第二种情况下,循环条件不依赖于循环体中发生的情况。 队列在for循环体中没有改变,当循环开始时,它预定义了将有多少次迭代。 所以我的结论就是这条线:
queue.remove(0).run()
搞砸了事情。 你能试试这个:
synchronized(queue)
{
for (int i = 0; i < queue.size(); i++)
{
queue.remove(0).run();
}
}
看看会发生什么。 此问题的可能原因可能是: - remove方法可能无法正常工作 - 循环内启动的线程可能会导致问题。
我刚试过这个(不是在Android中)并且它工作正常:
public class Main
{
public void run()
{
final Runnable runMe = new Runnable()
{
@Override
public void run()
{
System.out.println("Hi");
}
};
List<Runnable> queue = new ArrayList<Runnable>() {
private static final long serialVersionUID = 1L;
{
add(runMe); add(runMe); add(runMe); add(runMe);
}
};
synchronized(queue)
{
while(queue.size() > 0)
{
queue.remove(0).run();
}
}
}
public static void main(String[] args)
{
new Main().run();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.