gpt4 book ai didi

java - 在多线程中仅从链表中删除一次

转载 作者:行者123 更新时间:2023-11-30 10:13:59 25 4
gpt4 key购买 nike

假设我有一个 LinkedList 填充对象,每个对象存储我需要的相关信息。我有线程访问此列表的第一个元素以检索信息并对其执行一些操作,在操作结束时我希望从列表中删除第一个元素。如何确保每个元素只调用一次 remove()?这样每个线程都可以访问列表中相同的下一个元素?

public class Test {
private static LinkedList<foo> list;

public static void main(String args[]) {
list = new LinkedList<>();
list.add(foo1);
list.add(foo2);
list.add(foo3);
for(int i = 0; i < 5; i++) {
new Thread(run()).start();
}
}

private static Runnable run() {
while(true) {
while(SomeCondition) {
//Do work.
}
list.remove();
}
}
}

我已经尝试为删除方法创建一个锁,但这会导致所有线程的每个元素之间出现明显的滞后。有一个好主意吗

LinkedList<LinkedList<food>> mainList;

这样每个线程都有自己的工作列表?然后每个线程都可以这样做来访问它们的元素:

mainList.get(i).element();
mainList.get(i).remove();

编辑:我没有提到 main() 有它自己的线程,它不断地向列表中添加更多元素。主要目的是这是一个不断接收请求的服务器,请求作为“队列”放置在列表中。然后从 main() 分离出来的其他线程执行操作。请求的消息包含一个字段,让我知道哪个线程将执行什么操作。

编辑 2:我可能对获得正确答案的要求过于模糊,抱歉!这是一个不断从一个客户端接收请求的服务器,列表不断填充请求,为此目的最重要的字段是请求时间:

for(int i = 0; i < 5; i++) {
new Thread(run(i)).start();
}

private static Runnable run(int streamNumber) {
while(true) {
while(SomeCondition) {
//Do work.
}
list.remove();
}
}

那么 streamNumber 规定了以下内容:1. 我广播到哪个 IP 地址。2. 使用请求的时间和 streamNumber,它指向我需要使用的有效负载(来自文件)。

最后,每个线程都会将payload发送出去。所以每个线程需要相同的信息,但会做出不同的响应。一旦发送有效负载,它将获取下一个请求的时间并重新做所有事情。

最佳答案

首先,当多个线程正在访问列表以进行写操作时,LinkedList 只是一个糟糕的选择。你可以开始 here找到更适合此类需求的 其他 List 接口(interface)实现。

正如您自己评论的那样:另一种选择是将您的数据切片到单独的桶中,​​并将每个线程交给一个不同的桶。哪种解决方案能为您提供更好的结果取决于您的具体要求。创建桶需要前期成本,而线程安全队列会在您每次添加/删除元素时产生成本。

另一种方法:

  • 使用一个列表,但不要有 5 个线程遍历列表
  • 相反,您按顺序迭代列表,然后,对于每个 循环迭代,您获取一个列表条目,然后将 5 个任务对象推送到某个 ExecutorService 中。实例。

该服务之前已实例化,您可以将其基于 ThreadPool 或您想要的任何其他内容(甚至是单线程执行程序,这对单元测试非常有用)。这增加了一些开销,因为您必须创建这些任务对象,但它使其他一切变得更加简单。

关于java - 在多线程中仅从链表中删除一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51069283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com