如何使java.util.ArrayList线程安全[重复]

问题描述 投票:0回答:1

在我的程序中,我有一个类似于下面的逻辑,它抛出的是 ConcurrentModificationException. 我怎么能做 java.util.ArrayList 除了使用 CopyOnWriteArrayList (因为我在这个列表上有大量的写入,根据我的理解,在CopyOnWriteArrayList上写入是很贵的)

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

public class Test extends Thread {

    List<String> list = new ArrayList<String>();

    public static void main(String[] args) {
        Test t = new Test();
        t.start();

        System.out.println("in main thred");

        t.destory();

    }

    public void destory() {
        list.stream().toArray(String[]::new);
        System.out.println("done");

    }

    @Override
    public void run() {
        while(true) {
            list.add("test");
        }

    }
}

输出。

in main thred
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1388)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:546)
    at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:438)
java arraylist concurrency thread-safety concurrentmodification
1个回答
2
投票

你必须同步所有对列表的访问。

public void destory() {
    synchronized (list) {
      list.stream().toArray(String[]::new);
    }
    System.out.println("done");

}

    while(true) {
      synchronized (list) {
        list.add("test");
      }
    }

需要注意的是,仅仅将列表用 Collections.synchronizedList,因为这不会在整个迭代的过程中由流来保持监控。

© www.soinside.com 2019 - 2024. All rights reserved.