java:在不可变的 Iterable 上并发迭代

标签 java concurrency iterator iterable

我有一个不可变的 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/

相关文章:

java - 基于另一个 ComboBox 的项目禁用 JComboBox

Scala:您知道任何高级 Actors 文档/教程吗?

php - 处理并发问题的最佳方法

java - SonarQube 5.6 是否执行使用 sonar-plugin-api 版本 4.5.2 开发的插件中的装饰器?

java - 在 Java 中,如何有效地从 ArrayList<StringBuilder> 中删除重复项?

java - 并发应用程序不如单线程快

Java For 循环和多态性

java - 同一个集合 : do they have to return elements in the same order? 的两个 java.util.Iterators

c++ - 迭代循环和 lambda 函数

java - 如何在 Tomcat 服务器上使用 jfs 在 Java Web 应用程序中定义文件路径