![](/img/trans.png)
[英]How can i add elements to a PriorityQueue of Java Collections that are of different type?
[英]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.