Java 中 BlockingQueue 的异步等价物?

yan*_*976 5 java concurrency java-8

我正在寻找一个队列,它与java.util.concurrent.BlockingQueue. 它的界面将包括:

public interface AsynchronousBlockingQueue<E> {
    // - if the queue is empty, return a new CompletableFuture,
    //   that will be completed next time `add` is called
    // - if the queue is not empty, return a completed CompletableFuture,
         containing the first element of the list
    public CompletableFuture<E> poll();

    // if polling is in progress, complete the ongoing polling CompletableFuture.
    // otherwise, add the element to the queue
    public synchronized void add(E element);
}
Run Code Online (Sandbox Code Playgroud)

如果这很重要,那么应该只有一个轮询线程,并且轮询应该按顺序进行(poll轮询已经在进行时不会被调用)。

我希望它已经存在于 JVM 中,但我找不到它,当然我宁愿使用 JVM 中的东西而不是自己编写它。

另一个限制是,我被 Java 8 困住了(尽管我绝对有兴趣了解更新版本中存在的内容)。

yan*_*976 4

所以最后我写了自己的课程...对评论感兴趣:)

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;

public class AsynchronousBlockingQueue<E> {
    CompletableFuture<E> incompletePolling = null;
    Queue<E> elementsQueue = new LinkedList<>();

    // if the queue is empty, return a new CompletableFuture, that will be completed next time `add` is called
    // if the queue is not empty, return a completed CompletableFuture containing the first element of the list
    public synchronized CompletableFuture<E> poll() {
        // polling must be done sequentially, so this shouldn't be called if there is a poll ongoing.
        if (incompletePolling != null)
            throw new IllegalStateException("Polling is already ongoing");
        if (elementsQueue.isEmpty()) {
            incompletePolling = new CompletableFuture<>();
            return incompletePolling;
        }
        CompletableFuture<E> result = new CompletableFuture<>();
        result.complete(elementsQueue.poll());
        return result;
    }

    // if polling is in progress, complete the ongoing polling CompletableFuture.
    // otherwise, add the element to the queue
    public synchronized void add(E element) {
        if (incompletePolling != null) {
            CompletableFuture<E> result = incompletePolling;
            // removing must be done first because the completion could trigger code that needs the queue state to be valid
            incompletePolling = null;
            result.complete(element);
            return;
        }
        elementsQueue.add(element);
    }


}
Run Code Online (Sandbox Code Playgroud)