2011-12-14 72 views
0

我有一個web應用程序需要有時從url下載一些字節並將其打包併發送回請求者。下載的字節存儲了一段時間,以便在需要下載相同的URL時可以重新使用它們。我試圖找出如何最好地防止線程同時下載同一個網址,如果請求同時進入。我正在考慮創建一個如下所示的類,以防止同時下載相同的URL。如果一個url無法被鎖定,那麼它會等待,直到它不再被鎖定,只要它在解鎖後不存在,就嘗試下載它。在java中創建安全的多線程文件

public class URLDownloader 
{ 
    HashMap<String,String> activeThreads = new HashMap<String,String>(); 

    public synchronized void lockURL(String url, String threadID) throws UnableToLockURLException 
    { 
     if(!activeThreads.containsKey(url)) 
      activeThreads.put(url, threadID) 
     else 
      throw UnableToLockURLException() 
    } 

    public synchonized void unlockURL(String url, String threadID) 
    { 
     //need to check to make sure its locked and by the passed in thread 
     returns activeThreads.remove(url); 
    } 

    public synchonized void isURLStillLocked(String url) 
    { 
     returns activeThreads.contains(url); 
    } 

} 

有沒有人有更好的解決方案呢?我的解決方案似乎有效嗎?是否有任何開源組件已經做得非常好,我可以利用?

感謝

回答

0

聽起來好像你不需要鎖,因爲如果有多個請求下載相同的URL,是隻下載一次。

此外,我認爲在封裝方面更有意義的是將存儲的URL /例程的檢查存儲在URLDownloader類中的新URL中,而不是在調用類中。您的線索可以簡單地呼叫fetchURL(),並讓URLDownloader處理細節。

所以,你可以通過兩種方式來實現它。如果您沒有持續的下載請求流,更簡單的方法是隻有一個URLDownloader線程正在運行,並且要使其fetchURL方法​​,以便您一次只下載一個URL。否則,請將待處理的下載請求保留在中央LinkedHashSet<String>中,以保留順序並忽略重複。

1

我會建議保持ConcurrentHashSet<String>來跟蹤你的可見的唯一URL您的所有線程。這個構造可能並不直接存在於java庫中,但可以通過像這樣的ConcurrentHashMap輕鬆構建:Collections.newSetFromMap(new ConcurrentHashMap<String,Boolean>())