为什么我的arraylist的一次迭代工作,而另一次没有?

时间:2014-01-10 22:01:32

标签: java android loops

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循环失败?

2 个答案:

答案 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();
    }
}