多线程中的ArrayList上的java.util.ConcurrentModificationException

时间:2016-02-11 11:59:05

标签: java multithreading arraylist

你好在这里定义了两个线程EvenThread1& OddThread2。 EvenThread1从ArrayList打印偶数,并从列表中删除相应的值。相同的OddThread2也从同一个ArrayList打印奇数,并从列表中删除相应的值。 问题是,当我执行2或3次时,java.util.ConcurrentModificationException即将出现在控制台上。 即使我使用有效检查从列表中删除值。

if (j.intValue() >= 0)
{
    it.remove();
}

我知道为什么会这样,但我无法在这个程序中解决。 您能否建议我如何在以下程序中解释此异常以及解释?

 package MultiThreading;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    public class Eg2
    {

        public static void main(String[] args)
        {
        new EvenThread1();
        new OddThread2();

        }
    }

    class EvenThread1 implements Runnable
    {

        List<Integer> list = Services1.getNum();

        EvenThread1()
        {
        Thread th = new Thread(this);
        th.start();
        }

        @Override
        public void run()
        {
        Iterator<Integer> it = list.iterator();
        while (it.hasNext())
        {
            Integer j = (Integer) it.next();
            int a = j % 2;
            if (a == 0)
            {
            System.out.println("Even: " + j.intValue());
            if (j.intValue() >= 0)
            {
                it.remove();
                System.out.println("List Data=" + list);
            }

            }

        }

        }

    }

    class OddThread2 implements Runnable
    {

        List<Integer> list = Services1.getNum();

        OddThread2()
        {
        Thread th = new Thread(this);
        th.start();
        }

        @Override
        public void run()
        {
        Iterator<Integer> it = list.iterator();
        while (it.hasNext())
        {
            Integer j = (Integer) it.next();
            int a = j % 2;
            if (a != 0)
            {
            System.out.println("Odd: " + j.intValue());
            if (j.intValue() >= 0)
            {
                it.remove();
                System.out.println("List Data=" + list);
            }

            }

        }

        }

    }

    abstract class Services1
    {

        static List<Integer> list = new ArrayList<Integer>();

        static
        {
        for (int i = 0; i < 20; i++)
        {
            list.add(i);
        }
        }

        static public List<Integer> getNum()
        {
        return list;
        }

    }

2 个答案:

答案 0 :(得分:0)

    static List<Integer> list = Collections.synchronizedList(new ArrayList<Integer>());

您需要像上面的代码一样同步列表,因为它将是并发调用。

答案 1 :(得分:0)

ConcurrentLinkedDeque是一个类似列表的数据结构,支持并发操作。并且它可以返回报告Spliterator的{​​{1}}。这是一个好的开始。但是为了使解决方案能够工作,你需要能够创建两个Spliterator.CONCURRENT,一个用于平均而另一个用于赔率,并且他们必须能够跟踪它们各自的元素不知何故。泛化:给出实现分区策略的Spliterator Set,并确保所有跟踪它们自己的元素。

严格来说,这并非不可能。但是你没有开箱即用。你必须做一些有趣的(即棘手和容易出错的)编码才能使这样的事情发生。

玩得开心,把它放在Spliterator或类似的地方,当你完成它。 : - )