繁体   English   中英

当两个并发线程试图从CopyOnWriteArrayList中删除元素时会发生什么? java的

[英]What Happens When two concurrent threads try to remove elements from a CopyOnWriteArrayList? java

在JAVA中,当两个并发线程试图从同一CopyOnWriteArrayList删除某些元素时会发生什么? 会有不确定的行为吗? 例如,如果列表中有1-10个整数,并且1个线程删除了前5个整数,则2个线程删除了前3个整数。准确的结果是删除了前5个整数。 这样可以正常工作吗?

CopyOnWriteArrayList的行为将取决于您使用的方法。

如果使用一个线程中的5个线程和另一个线程中的3个线程执行remove(int index) ,则将删除8个元素,尽管未定义哪个线程获取哪个元素。

如果您确实对一个线程中的5个值执行remove(Integer element) ,而在另一个线程中对前3个值进行了操作,只要没有重复项,则将删除前5个元素。 前三个元素可以被任一线程删除,而没有删除的线程将返回false元素

如果按索引删除,则总共将删除8(5 + 3)个元素。 因为,在一个线程删除一个元素之后,新的CopyOnWriteArrayList的元素要少于早先对其执行删除的元素。

package com.copyonwrite;

import java.util.concurrent.CopyOnWriteArrayList;

public class Main {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> cop = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10; i++)
            cop.add(Integer.toString(i));
        new Thread(new DeleteRunnable(cop, 5)).start();
        new Thread(new DeleteRunnable(cop, 3)).start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("size " + cop.size());
    }

    public static class DeleteRunnable implements Runnable {

        CopyOnWriteArrayList<String> cop;
        int cnt;

        public DeleteRunnable(CopyOnWriteArrayList<String> cop, int cnt) {
            this.cop = cop;
            this.cnt = cnt;
        }

        @Override
        public void run() {
            for (int i = 0; i < cnt; i++)
                cop.remove(i);
        }

    }
}

输出:大小2

CopyOnWriteArrayList实际上是在多线程环境中使用的,其最佳结果是写入次数较少,读取次数较多

所有线程都携带List的副本 ,并且原始列表保持不变。 在执行任何添加/删除操作之前,Monitor会查看原始列表,每次您写入列表时都会复制整个列表,例如添加元素或删除元素并进行synchronization

当您的列表太大时,这可能会非常昂贵。 这意味着当我们进行少量修改但读取很多时, CopyOnWriteArrayList最为有用,因为读取非常便宜并且不需要同步。

根据此处的文档,

java.util.ArrayList的线程安全变体,其中所有可变操作(添加,设置等)都通过对基础数组进行全新复制来实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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