簡體   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