繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM