- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个不可变的 Iterable<X>
有大量的元素。 (它恰好是 List<>
但没关系。)
我想做的是启动一些并行/异步任务来迭代 Iterable<>
使用相同的迭代器,并且我想知道我应该使用什么接口(interface)。
这是一个带有待定接口(interface)的示例实现 QuasiIteratorInterface
:
public void process(Iterable<X> iterable)
{
QuasiIteratorInterface<X> qit = ParallelIteratorWrapper.iterate(iterable);
for (int i = 0; i < MAX_PARALLEL_COUNT; ++i)
{
SomeWorkerClass worker = new SomeWorkerClass(qit);
worker.start();
}
}
class ParallelIteratorWrapper<T> implements QuasiIteratorInterface<T>
{
final private Iterator<T> iterator;
final private Object lock = new Object();
private ParallelIteratorWrapper(Iterator<T> iterator) {
this.iterator = iterator;
}
static public <T> ParallelIteratorWrapper<T> iterate(Iterable<T> iterable)
{
return new ParallelIteratorWrapper(iterable.iterator());
}
private T getNextItem()
{
synchronized(lock)
{
if (this.iterator.hasNext())
return this.iterator.next();
else
return null;
}
}
/* QuasiIteratorInterface methods here */
}
这是我的问题:
使用 Iterator
没有意义直接,因为 hasNext() 和 next() 有一个同步问题,如果其他人在你之前调用 next(),那么 hasNext() 就没用了。
我喜欢使用 Queue
, 但我需要的唯一方法是 poll()
我喜欢使用 ConcurrentLinkedQueue 来保存我的大量元素...除非我可能不得不多次遍历这些元素,所以我不能使用它。
<有什么建议吗?
最佳答案
使用 poll()
方法或等效方法(例如 Guava 的 Supplier
)创建您自己的 Producer
接口(interface)。实现选项有很多,但如果你有一个不可变的随机访问列表,那么你可以简单地维护一个线程安全的单调计数器(例如 AtomicInteger)并调用 list.get(int) 例如:
class ListSupplier<T> implements Supplier<T> {
private final AtomicInteger next = new AtomicInteger();
private final List<T> elements; // ctor injected
…
public <T> get() {
// real impl more complicated due to bounds checks
// and what to do when exhausted
return elements.get(next.getAndIncrement());
}
}
这是线程安全的,但您可能希望在耗尽时返回 Option 样式的东西或 null。
关于java:在不可变的 Iterable 上并发迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5903079/
COW 不是奶牛,是 Copy-On-Write 的缩写,这是一种是复制但也不完全是复制的技术。 一般来说复制就是创建出完全相同的两份,两份是独立的: 但是,有的时候复制这件事没多大必要
我是一名优秀的程序员,十分优秀!