繁体   English   中英

如何在 java 中同时添加和删除 collections 中的元素?

[英]how to add and remove elements in collections simultaneously in java?

我正在尝试同时添加元素并删除列表中的元素。 如何解决这个问题?

public class Main3 {
    public static void main(String[] args) throws InterruptedException {
        Vector<Integer> list = new Vector<>();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                list.add(i);
                System.out.println("add " + i);
            }
        });
        t1.start();
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("removed " + i);
                list.remove(i);
            }
        });
        t2.start();
    }
}
    

我得到以下 output:

**Error**

add 0
add 1
add 2
add 3
add 4
add 5
add 6
add 7
removed 0
add 8
add 9
removed 1
removed 2
removed 3
removed 4
removed 5
Exception in thread "Thread-1" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 5
    at java.base/java.util.Vector.remove(Vector.java:875)
    at com.zoho.Main3.lambda$1(Main3.java:23)
    at java.base/java.lang.Thread.run(Thread.java:829)

第一个问题:

正如您从评论中看到的那样,通过在您的删除部分使用 for 循环,您正在尝试删除一个不存在的项目。

到底是怎么回事?

先说羊吧。

你有 10 只羊,每只羊都有一个数字 0 - 9。你的任务是移走所有的羊。

由于您是一名软件开发人员,并且担心您可能会迷失方向,因此您决定保留索引。 您将索引设置为 0 并开始移除绵羊; 移除一只绵羊后,您将索引设为 1,直到达到第 9 位。

您首先移除第一只羊(编号 0)。 然而,这里有一个问题,每次你移走一只羊,它们都会被分配一个新的数字。

Sheep 0 is gone,
Sheep 1 becomes 0, 
Sheep 2 becomes 1... 

但问题是你没有更新你的索引。

所以所有的回合 go 都很好 -> 直到你试图删除Sheep 5 羊 5 不存在。 因为最高的绵羊数只有 4 只。

既然没有羊,你什么也抓不到,什么也拿不走,然后糊涂了:)

如何解决?

你可能在想; 我会在每一轮之后更新我的索引。 不不不! 不好的做法:) 不这样做对你有好处。

让我们使用一些不同的逻辑而不是保留索引。 您执行以下操作。 总是移走最后一只羊,直到没有剩下的为止。 为什么是最后一个? 如果我们删除最后一个,我们甚至不需要在每一轮之后重命名它们:) 超级方便。 在编程术语中,让我们使用 while (list.size() > 0) 代替 for 循环/索引。

第二个问题

由于两个线程(工作者)同时运行。 您可以比其他人添加羊更快地移除羊。 因此,移走工人可以移走一只羊,然后说:哇,没有羊了,今天结束了……当他离开农场时,你又添加了九只羊。

为了解决这个问题,我们告诉 Remove worker 仅在添加了所有羊后才开始。 我们可以通过简单地在第一个线程上调用一个连接来做到这一点。 (见下面的代码)

现在——你可能会想——使用并发到底有什么好处? 好吧,你可以有多个 Remove 工人和多个 Add 工人:你的 CPU 确实是极限:)

解释的代码

public static void main(String[] args) throws InterruptedException {
    Vector<Integer> list = new Vector<>();
    Thread t1 = new Thread(() -> {
        for (int i = 0; i < 10; i++) {
            list.add(i);
            System.out.println("add " + i);
        }
    });
    t1.start();
    t1.join();

    Thread t2 = new Thread(() -> {
        while (list.size() > 0) {
            System.out.println("removed t2");
            list.remove(list.size() - 1);
        }
    });
    t2.start();
}

最后的评论:

乐趣从这里开始……你很快就会发现:有些羊饿死了,工人永远在等待,有些工人抓羊太久了……享受吧:)

暂无
暂无

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

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