Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The linked implementation appears to have been written for Java 4 and can be simplified a little using guava and <code>java.util.concurrent</code>:</p> <pre><code>import java.util.Iterator; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; import com.google.common.base.Throwables; import com.google.common.collect.AbstractIterator; import com.google.common.util.concurrent.Executors; public abstract class Iterators2 { public static &lt;E&gt; Iterator&lt;E&gt; buffer(final Iterator&lt;E&gt; source, int capacity) { return buffer(source, capacity, defaultExecutor); } public static &lt;E&gt; Iterator&lt;E&gt; buffer(final Iterator&lt;E&gt; source, int capacity, final ExecutorService exec) { if (capacity &lt;= 0) return source; final BlockingQueue&lt;E&gt; queue = new ArrayBlockingQueue&lt;E&gt;(capacity); // Temporary storage for an element we fetched but could not fit in the queue final AtomicReference&lt;E&gt; overflow = new AtomicReference&lt;E&gt;(); final Runnable inserter = new Runnable() { @SuppressWarnings("unchecked") public void run() { E next = (E) END_MARKER; if (source.hasNext()) { next = source.next(); // ArrayBlockingQueue does not allow nulls if (next == null) next = (E) NULL_MARKER; } if (queue.offer(next)) { // Keep buffering elements as long as we can if (next != END_MARKER) exec.submit(this); } else { // Save the element. This also signals to the // iterator that the inserter thread is blocked. overflow.lazySet(next); } } }; // Fetch the first element. // The inserter will resubmit itself as necessary to fetch more elements. exec.submit(inserter); Iterator&lt;E&gt; iterator = new AbstractIterator&lt;E&gt;() { protected E computeNext() { try { E next = queue.take(); E overflowElem = overflow.getAndSet(null); if (overflowElem != null) { // There is now a space in the queue queue.put(overflowElem); // Awaken the inserter thread exec.submit(inserter); } if (next == END_MARKER) { return endOfData(); } else if (next == NULL_MARKER) { return null; } else { return next; } } catch (InterruptedException ex) { Thread.currentThread().interrupt(); return endOfData(); } } }; return iterator; } protected Iterators2() { throw Throwables.propagate(new InstantiationException(Iterators2.class + " is a static class and cannot be instantiated")); } private static ExecutorService defaultExecutor = java.util.concurrent.Executors.newCachedThreadPool(Executors.daemonThreadFactory()); private static final Object END_MARKER = new Object(); private static final Object NULL_MARKER = new Object(); } </code></pre> <hr> <p>Note: the above implementation makes no attempt to handle exceptions in the source iterator (if one is thrown, the inserter task will terminate abruptly, leaving the calling thread deadlocked.)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload