【问题标题】:How to implement a FIFO queue in a multi-threaded environment如何在多线程环境中实现 FIFO 队列
【发布时间】:2020-06-02 17:56:10
【问题描述】:

我正在尝试为一个获取 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);
    }
}

【问题讨论】:

  • OpenGraphFetcherImpl 是单例吗?如果是这样,只需使 fetch 方法同步。如果它不是单例,则声明一个静态对象,并使用它在入口处进行同步以获取,以便在任何给定时间只有一个线程可以调用它。
  • 这是一个单例。也就是说,我可以使 fetch() 同步,但如果 useProxy(url) 为 false,我也希望 fetch() 不同步,因为该服务允许同时请求非代理调用。在代码的“if(useProxy(url))”部分之后调用另一个名为“private synchronized fetchProxy()”的方法是否有意义?

标签: java multithreading queue synchronized


【解决方案1】:

根据您的描述,当useProxy 为真时,您希望限制对 fetch() 的同步调用。然后,您可以使用对象仅同步该案例:

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);
        }
    }
...

【讨论】:

    猜你喜欢
    • 2014-08-24
    • 1970-01-01
    • 2014-11-29
    • 2023-04-03
    • 2017-04-08
    • 2010-11-29
    • 1970-01-01
    • 2020-03-09
    • 2012-04-30
    相关资源
    最近更新 更多