我正在一个项目队列上启动一个长时间运行的进程,当一个项目被安排处理或正在处理时,我想禁止一些其他操作。我的代码基本上是这样的:
public class LongRunningProcess extends Thread {
private final ConcurrentLinkedQueue<Item> pending = new ConcurrentLinkedQueue<>();
private final Set<Item> active = Collections.newSetFromMap(new ConcurrentHashMap<Item, Boolean>());
public LongRunningProcess() {
// add items to pending; no more items will ever be added
}
@Override
public void run() {
while (! pending.isEmpty()) {
// The peek/add/remove pattern here is important. The number
// of items that are active or scheduled is always decreasing.
// Because isScheduled checks pending before checking active,
// this order of operations ensures that we never miss an item
// as it is being switched from one collection to the other.
Item nextItem = pending.peek();
active.add(nextItem); // <---Can any of these get reordered?
pending.remove(); // <---+
processItem(nextItem); // <---+
active.remove(nextItem); // <---+
}
}
public boolean isScheduled(Item item) {
return pending.contains(item) || active.contains(item);
}
}
这会按我预期的方式工作,还是可以重新排序上面突出显示的代码块?你能指点我任何相关的规格吗?
编辑:
@Banthar 的有用评论让我找到了java.util.concurrent 包文档,它明确地回答了我的问题:
所有类
java.util.concurrent
及其子包中的方法都将这些保证扩展到更高级别的同步。尤其是:
- 在将对象放入任何并发集合之前线程中的操作发生在另一个线程中从集合中访问或删除该元素之后的操作。