簡體   English   中英

如何在多線程環境中實現 FIFO 隊列

[英]How to implement a FIFO queue in a multi-threaded environment

我正在嘗試為 class 實現一個隊列,該隊列為 url 獲取OpenGraph數據。 這個想法是,如果請求需要他們的“代理”服務, OpenGraphIO服務一次只允許一個請求。 為了消除服務中的“同時代理請求”錯誤,我想在名為OpenGraphFetcherImpl的服務 class 中實現一個請求隊列。 但是,我不知道如何在fetch()方法中實現實際隊列本身。 顯然fetch()方法可以在多線程環境中調用。

我的 class shell 如下:

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

根據您的描述,您希望在useProxy為 true 時限制對 fetch() 的同步調用。 然后,您可以使用 object 僅同步該案例:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM