如何在多线程环境下实现FIFO队列?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在多线程环境下实现FIFO队列?相关的知识,希望对你有一定的参考价值。

我正试图为一个类实现一个队列,以获取 OpenGraph url的数据。 这个想法是 OpenGraphIO 服务一次只允许一个请求,如果该请求需要他们的 "代理 "服务。为了消除服务中的 "同时代理请求 "错误,我想在服务类里面实现一个请求队列,叫做 OpenGraphFetcherImpl. 然而,我不知道如何在这个队列中实现实际的队列本身。fetch() 的方法。 显然 fetch() 方法可以在多线程环境下调用。

我的类壳如下。

public class OpenGraphFetcherImpl implements OpenGraphFetcher {

    private static final String[] domainsThatRequireProxy = {"instagram.com","facebook.com"};

    private static final LinkedList<URL> proxyQueue = new LinkedList<>();

    private final String api_key;

    public OpenGraphFetcherImpl(String api_key) {
        this.api_key = api_key;
    }

    /**
     * Fetch OpenGraph information for a url.  If the url is invalid or no data is returned, the OpenGraph
     * object will be "empty" (non-null)
     * 
     * Only one "proxy" request can be made at a time. Should a proxy be needed, the request will be queued
     * and returned once previous requests have been completed.
     *
     * @param url end point to fetch OpenGraph data
     * @return OpenGraph object
     */
    @Override
    @Nonnull
    public OpenGraph fetch(URL url) {
        if (useProxy(url)) {
            // Clearly this code doesn't work, but logic should be to add the request to the queue and then make requests in FIFO order
            proxyQueue.add(url);
            return OpenGraphIO.fetchOpenGraphInfo(api_key, proxyQueue.poll(), true);
        } else {
            return OpenGraphIO.fetchOpenGraphInfo(api_key, url, false);
        }
    }

    /**
     * @param url url to test
     * @return true if the host of the url matches any domains that require use of a proxy
     */
    private boolean useProxy(URL url) {
        return Arrays.stream(domainsThatRequireProxy).parallel().anyMatch(url.getHost()::contains);
    }
}
答案

根据你的描述,你想限制同步调用fetch(),当 useProxy 为真。那么,你可以使用一个对象来同步该情况下只。

public class OpenGraphFetcherImpl implements OpenGraphFetcher {
    private static final Object fetchLock=new Object();

     public OpenGraph fetch(URL url) {
        if (useProxy(url)) {
            synchronized(fetchLock) {
               return OpenGraphIO.fetchOpenGraphInfo(api_key, url, true);
            }
        } else {
            return OpenGraphIO.fetchOpenGraphInfo(api_key, url, false);
        }
    }
...

以上是关于如何在多线程环境下实现FIFO队列?的主要内容,如果未能解决你的问题,请参考以下文章

无锁队列的实现

python 生产者与消费者模式

复习打卡--0823 队列和多进程

Spring在多线程环境下如何确保事务一致性

Spring在多线程环境下如何确保事务一致性

在多线程中使用链表队列