1

我正在学习 CopyOnWriteArrayList ,但根据我的理解它不能正常工作。我有两个线程,一个是主线程,另一个是内线程。主线程正在从 CopyOnWriteArrayList 集合中删除对象,而内部线程正在休眠 5 秒。主线程在内部线程迭代之前完成了删除操作,但内部线程仍在迭代整个集合,我的意思是由主线程删除。

package com.kalavakuri.javaconcurrent;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ConcurrentModificationExceptionExample {

    private static List<String> strings = new CopyOnWriteArrayList<String>();

    public static void main(String[] args) {

        strings.add("Ram");
        strings.add("Ravi");
        strings.add("Raju");
        strings.add("Raghu1");
        strings.add("Raghu2");
        strings.add("Raghu3");
        strings.add("Raghu4");
        strings.add("Raghu5");
        strings.add("Raghu6");

        Thread thread = new Thread(() -> {
            Iterator<String> iterator = strings.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
                System.out.println("Thread name " + Thread.currentThread().getName());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Inner thread");

        thread.start();

        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String value = iterator.next();
            strings.remove(value);
            System.out.println("Thread name " + Thread.currentThread().getName());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        strings.forEach(v -> System.out.println(v));

    }
}

我期望内部线程不应该迭代由主线程删除的对象。如果我的理解有误,请纠正我。

4

1 回答 1

4

是的,你错了。从文档

“快照”样式的迭代器方法使用对创建迭代器时数组状态的引用。这个数组在迭代器的生命周期内永远不会改变,所以干扰是不可能的,并且迭代器保证不会抛出 ConcurrentModificationException。

因此,按照设计,当其他线程进行更改时,迭代器不会更改。

于 2019-06-09T14:12:45.653 回答