【发布时间】:2018-06-27 18:27:19
【问题描述】:
假设我有一个 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();
}
}
}
我尝试为 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发送出去。所以每个线程都需要相同的信息,但会做出不同的反应。一旦它发送了有效载荷,它将抓住下一个请求的时间并重新做所有事情。
【问题讨论】:
-
您是否考虑过为每个线程提供其自己的(浅)列表副本?
-
或者如果线程没有通过从列表中提取的对象交换数据,那么您甚至可以制作一个 deep 副本。
-
你能详细说明一下吗?我的下一个思路是创建充满列表的列表,然后每个线程都可以处理自己的列表副本
-
您现在是在问如何表示列表副本吗?我在这里要做的第一件事就是停止依赖类变量。让每个线程的列表成为单独的
Runnable的实例变量对我来说是有意义的,通过该变量定义线程的工作。您的代码在这个一般区域中被破坏了,但是您可以将列表副本传递给获取Runnables 的方法或构造函数。 -
对不起!我想我应该包括不断添加列表的事实,因此制作深层副本效率不高。
标签: java multithreading linked-list