【问题标题】:Is it safe to perform read and "set" operation on List by different threads without locking mechanism不同线程在没有锁定机制的情况下对 List 执行读取和“设置”操作是否安全
【发布时间】:2015-04-16 02:04:29
【问题描述】:

迭代List 是非常不安全的,它正在由另一个线程执行添加/删除 操作。

这就是为什么我们需要CopyOnWriteArrayList

public static void main(String[] args) throws InterruptedException {
    List<String> list = new ArrayList<>();

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                // java.util.ConcurrentModificationException
                for (String s : list) {
                    System.out.println(s);
                }
            }
        }

    });
    thread.start();

    for (int i=0; i<1000; i++) {
        list.add("string" + i);    
    }

    Thread.sleep(Long.MAX_VALUE);
}

但是,设置操作怎么样。目前,以下代码没有抛出任何异常。

public static void main(String[] args) throws InterruptedException {
    List<String> list = new ArrayList<>();
    list.add("dummy");

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                for (String s : list) {
                    System.out.println(s);
                }
            }
        }

    });
    thread.start();

    for (int i=0; i<1000; i++) {
        list.set(0, "smart");
    }

    Thread.sleep(Long.MAX_VALUE);
}

即使没有任何意外的结果,我想知道,如果线程只对List执行set操作,我们不使用任何锁定是否是一个好习惯机制,还是copy n write机制?

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    引用ArrayList的javadoc:

    请注意,此实现不同步。如果多个线程同时访问一个 ArrayList 实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。 (结构修改是添加或删除一个或多个元素或显式调整后备数组大小的任何操作;仅设置元素的值不是结构修改。)

    所以不,它不需要同步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-15
      • 1970-01-01
      • 2021-10-03
      • 2023-02-13
      • 2010-11-23
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      相关资源
      最近更新 更多