( 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循环失败?
答案 0 :(得分:1)
实际上我不能提到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();
}
}
看看会发生什么。 出现此问题的可能原因可能是: - 删除方法可能无法正常工作 - 循环内启动的线程可能会导致问题。
答案 1 :(得分:0)
我刚试过这个(虽然不是在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();
}
}