Безопасное создание многопоточных файлов в Java - PullRequest
0 голосов
/ 14 декабря 2011

У меня есть веб-приложение, которому иногда нужно загрузить несколько байтов из URL-адреса, упаковать его и отправить обратно запрашивающей стороне.Загруженные байты сохраняются в течение некоторого времени, поэтому их можно использовать повторно, если для загрузки требуется тот же URL-адрес.Я пытаюсь выяснить, как лучше всего не допустить, чтобы потоки загружали один и тот же URL-адрес одновременно, если запросы приходят одновременно.Я думал о создании класса, подобного приведенному ниже, который предотвратил бы одновременную загрузку одного и того же URL.Если URL-адрес не может быть заблокирован, он либо ждет, пока его не заблокируют, чтобы попытаться загрузить его, если он не существует после разблокировки.

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

}

У кого-нибудь есть лучшее решение для этого?Мое решение кажется верным?Существуют ли какие-либо компоненты с открытым исходным кодом, которые уже делают это очень хорошо, что я могу использовать?

Спасибо

Ответы [ 2 ]

1 голос
/ 14 декабря 2011

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

0 голосов
/ 14 декабря 2011

Звучит так, как будто вам не нужна блокировка, поскольку, если есть несколько запросов на скачивание одного и того же URL-адреса, необходимо загрузить его только один раз.

Кроме того, я думаю, что с точки зрения инкапсуляции было бы более целесообразно поставить проверку сохраненного URL / подпрограммы для хранения новых URL-адресов в классе URLDownloader, а не в вызывающих классах. Ваши темы могут просто позвонить, например, fetchURL(), и пусть URLDownloader обрабатывает специфику.

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

...