Стратегия в Java для очистки / удаления неиспользуемых элементов карты - PullRequest
0 голосов
/ 02 ноября 2009

В моем веб-приложении реализован «менеджер», который можно вызывать для определения и определения контекста веб-сайта, в котором находится текущий поток (мы помечаем наш сайт так, чтобы контекст веб-сайта представлял, на каком сайте мы находимся) )

Я пытаюсь определить, какая стратегия лучше для этого, в настоящее время я реализую хранилище потоков в WebSiteContexts в параллельной хэш-карте:

private final ConcurrentHashMap<Thread, WebSiteContext> chm = new ConcurrentHashMap<Thread, WebSiteContext>();

в начале потока (либо через фильтр сервлетов, либо через ручную настройку) поток будет связан с его WebSiteContext,

но хотите очистить карту, чтобы избежать утечки памяти. Поэтому я предполагаю, что одна стратегия состоит в том, чтобы перебирать ключи потока карты, чтобы выяснить, являются ли потоки «живыми» (thread.isAlive ()) и, если нет, удалить их, например, так:

 public class Cleaner implements Runnable {
      private static final int INTERVAL = 6 * 1000; // 6 seconds
      public Cleaner() {
      }
      public void run() {
            // soo every interval iterate through the threads if they're dead then remove it from the map.
            while(true) {
               try {
                     Set<Thread> threads = chm.keySet();
                     Set<Thread> staleThreads = new HashSet<Thread>();
                     for (Thread tmpThread : threads) {

                        // if we get to a dead thread then clean the fucker up
                        if (!tmpThread.isAlive()) {
                           // think that we're going to get a run condition anyway
                           chm.remove(tmpThread);
                        }
                     }
                  Thread.sleep(INTERVAL);
               } catch (Exception e) {
                  log.error("caught exception e:", e);
               }
            }
      }
   }

, но это, я полагаю, требует от меня синхронизации доступа к карте (или нет?), Чего я хочу избежать.

Существует ли какой-либо "идиоматический" шаблон для хранения атрибутов в потоках в java или очистки карт, в которых объекты потоков являются ключами? Я открыт для использования WeakReference / SoftReferences или даже если есть какой-то эквивалент Thread.getCurrentThread (). SetAttribute (Object, Object), это было бы здорово

Приветствие Симон Б

Ответы [ 4 ]

2 голосов
/ 02 ноября 2009

Вы думали о ThreadLocal?

1 голос
/ 02 ноября 2009

Ваш подход может сработать, но в итоге вы будете выполнять больше работы, чем нужно. ThreadLocal - это то, что вы ищете. Это позволит вам хранить объекты, связанные с каждым потоком в вашем приложении. Типичный способ его использования - реализовать метод initialValue (), который присваивает ему первое значение. Пример:

 private static final ThreadLocal<String> localAttribute = new ThreadLocal<String> () {
         protected Integer initialValue() {
             return "InitialValue";
     }
 };

Это даст вам новый локальный поток с начальным значением «InitialValue» при первом вызове localAttribute.get (). Затем вы можете вызвать localAttribute.set (), чтобы присвоить ему другое значение. Каждый запрашивающий поток будет иметь разные значения для одного и того же атрибута.

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

0 голосов
/ 02 ноября 2009

Вы определяете переменную «локальный поток» для продолжительности одного вызова сервлета. Лучший способ - удалить отображение на том же уровне, на котором вы его добавили, поэтому, если вы добавите на карту в ServletFilter, я бы добавил блок finally, который удалил отображение на выходе. То же самое относится и к «ручному» добавлению в сервлете.

Альтернативы имеют эту информацию в вашем ServletContext или добавляют ее как атрибут ThreadLocal.

0 голосов
/ 02 ноября 2009
  • java.lang.ThreadLocal ;
  • привязать информацию о цели к атрибуту запроса сервлета;
...