我正在构建一个java Running类,它将逐个处理一组项目。
工作时(run
ning),该组可能会更新(仅添加项目)。
如何通过确定它将考虑新添加的元素来循环该列表?
更新:根据答案(谢谢!),我实施了代码I suggested on CodeReview。
答案 0 :(得分:4)
您应该使用Queue
,即java.util.concurrent.ConcurrentLinkedQueue
,java.util.concurrent.LinkedBlockingQueue
,java.util.concurrent.ArrayBlockingQueue
或其他适合您需求的实现。
他们有不同的方法,允许您实现不同的方案。您可以检查javadocs Queue
方法之间的差异(有方法抛出异常,或返回空值;查看元素或通过删除检索元素的方法)。
抛出异常返回特殊值
插入add(e)offer(e)
删除remove()poll()
检查element()peek()
在BlockingQueue
实现的情况下,还有2个选项:阻塞超时的方法和方法。可能方法的扩展表位于javadoc。
仔细选择所需的实施方案。你想要一个固定的容量吗?你想阻止从空队列中检索吗?你想要你的队列有界或无界。如果仍有疑问,请查看Stack Overflow答案,解释不同队列类型之间的差异,Google或者检查javadocs。
根据您的设计,您可能会遇到或可能不会遇到一个问题 - 如何告诉队列是空的,因为您已经完成了生成元素。您的生产者(无论是将哪些元素插入队列)都不够快,无法在消耗之前将项目添加到队列中?或者队列是否为空,因为所有任务都在哪里完成?在后一种情况下,如果使用阻塞队列,则可以阻止在没有可用时检索元素。在这种情况下,你可以考虑一个非阻塞队列,使用“毒丸”标记元素,这意味着生产者通过使用保存队列和生产者/消费者交互的中间介体类来完成生产,甚至更好地将生产者与消费者分离只有调解员。
答案 1 :(得分:3)
使用队列(例如,java.util.concurrent.LinkedBlockingQueue)而不是列表。队列专门针对这种情况而设计。
答案 2 :(得分:1)
不要使用List。
如果我使用Queue
实例,则可以调用remove()
,然后按FIFO顺序检索元素。如果您使用List
实例,则无法做出此类保证。
以下面的代码为例:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(4);
list.add(3);
list.add(2);
list.add(1);
list.set(4,5);
list.set(3,4);
list.set(2,3);
list.set(1,2);
list.set(0,1);
System.out.println(list);
另外,另一个区别是抽象。使用Queue
实例,您不必担心索引,如果您不需要List
提供的所有内容,这会让您更容易思考。