2017-02-08 5 views
0

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

Скажем, что поток работает каждые 24 часа в полночь. В полночь кеш очищается, а затем обновляется данными из базы данных. Во время процесса обновления, как я могу получить доступ к этому кешу только после того, как поток завершил обработку? Конечно, я могу гарантировать, что кеш не пуст. Однако есть ли другой способ сделать это?

Я знаю, что этот вопрос неясен. Я ищу ресурсы, которые можно указать на мои собственные исследования и исследования.

+0

После обновления вы хотите, чтобы кеш был доступен до следующей полуночи или на короткое время?Если первое, почему бы просто не установить его в какое-либо общедоступное место (например, поле с геттером)? Любой может читать с этого места, и до тех пор, пока переменная не является нулевой, это то, что они должны использовать. Конечно, есть проблемы с резьбой, но это само по себе. – yshavit

+0

В этом примере, который я представил, это будет до следующей полуночи. Основываясь на вашем примере, я бы не должен был хранить в переменной, а затем переписать переменную в какой-то момент? По сути, я хочу, чтобы избежать взаимодействия с этой переменной до тех пор, пока не произойдет обновление. – Albert

+0

Если взаимодействия - это просто «сохранить ссылку, а затем использовать эту локальную ссылку для всего, что вам нужно», тогда почему вас это волнует, если кто-то использует его? Иными словами: как все иначе, если кто-то правильно забирает предыдущую версию в 11:58 вечера, а «неправильно» подбирает ту же самую версию в 12:01, а новый кеш рассчитывается? – yshavit

ответ

0

Использовать флаг canGet = true; перед обновлением данных из db, сделайте этот флаг ложным теперь очистите карту и загрузите ее Это похоже на способ, который вы предложили, за исключением того, что переменная обновляется только после завершения обновления. По завершении обновления установите flag to true.

при получении данных с карты, установите флаг, если он доступен получить значение из карты

Примечания: Сделать этот флаг летучего

0

cacheThread: каждый 24 часа

mainThread: ваш поток чтобы проверить, заполнена ли карта или нет.

Существует несколько способов. Проще всего было бы установить связь между этими двумя потоками, используя инструменты связи низкого уровня, такие как ожидание и уведомление на одном объекте и использование переменной флага. Если основной поток будет ждать, пока флаг не станет ложным, и как только флаг будет установлен, поток кеша уведомит основной поток.

Другие сложные способы включают использование CyclicBarrier/Phaser. С CycliBarrier вы можете предоставить один барьерный объект для обоих потоков, а начальные стороны - 2, поэтому, когда оба потока вызовут метод ожидания, основной поток будет продолжаться, и основной поток также сбросит барьер, чтобы его можно было использовать на следующий день.

mainThread{ 
    //some code 

     barrier.await(); 

    //barrier.reset 
    //required processing on map 

} 
cacheThread{ 
    //Fill map 
     barrier.await(); 

} 
0

Say нить проходит через каждые 24 часов в полночь. В полночь кеш очищается, а затем обновляется данными из базы данных. Во время процесса обновления, как я могу получить доступ к этому кешу только после того, как поток завершил обработку?

Это очень распространенный образец с рядом ответов. Я стараюсь никогда не очищать кеш, но вместо этого я заменяю кеш новым.

private volatile Map<?, ?> cacheMap = new HashMap<>(); 
... 
private void updateCache() { 
    Map<?, ?> newCacheMap = new HashMap<>(); 
    // ... fill out the newCacheMap somehow 
    // once it is filled out then you can replace the one in use 
    this.cacheMap = newCacheMap; 
} 

Важно отметить volatile поле, чтобы убедиться, что нити см полностью опубликованный кэш при запуске.

Если кеш слишком большой в памяти, чтобы иметь 2 копии (старый и новый), я бы предложил вам перейти на использование ConcurrentHashMap и добавить время ожидания для каждого из элементов. Затем вы можете обновить карту кэша на лету. Фоновая нить добавит к ней новые элементы и удалит старые элементы «на лету». Или он может запускать записи в кеше и обновлять их в реальном времени, переставляя их на карту.