- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有一个 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)实现。
正如您自己评论的那样:另一种选择是将您的数据切片到单独的桶中,并将每个线程交给一个不同的桶。哪种解决方案能为您提供更好的结果取决于您的具体要求。创建桶需要前期成本,而线程安全队列会在您每次添加/删除元素时产生成本。
另一种方法:
该服务之前已实例化,您可以将其基于 ThreadPool 或您想要的任何其他内容(甚至是单线程执行程序,这对单元测试非常有用)。这增加了一些开销,因为您必须创建这些任务对象,但它使其他一切变得更加简单。
关于java - 在多线程中仅从链表中删除一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51069283/
我是一名优秀的程序员,十分优秀!