2011-12-14 5 views
0

У меня есть webapp, который иногда должен загружать некоторые байты из URL-адреса и упаковывать его и отправлять обратно запрашивающему. Загруженные байты хранятся ненадолго, поэтому их можно использовать повторно, если для загрузки требуется один и тот же 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/подпрограммы для хранения новых URL-адресов в классе URLDownloader, а не в вызывающих классах. Ваши потоки могут просто звонить, например. fetchURL(), и пусть URLDownloader справится с особенностями.

Итак, вы можете реализовать это двумя способами. Если у вас нет постоянного потока запросов на скачивание, проще использовать только один поток URLDownloader и сделать его fetchURL метод synchronized, чтобы вы загружали только один URL за раз. В противном случае сохраните ожидающие запросы на загрузку в центральном LinkedHashSet<String>, который сохраняет порядок и игнорирует повторы.

1

Я хотел бы предложить, чтобы держать ConcurrentHashSet<String> следить за вашими уникальную URL-адресов, видимых все потоки. Эта конструкция может отсутствовать непосредственно в java-библиотеке, но может быть легко сконструирована с помощью ConcurrentHashMap следующим образом: Collections.newSetFromMap(new ConcurrentHashMap<String,Boolean>())

Смежные вопросы