![](/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.