2014-07-09 4 views
0

시간 경과 후 HashMap에 추가 된 항목에 대해 특정 작업을 수행하려는 HashMap이 있습니다.HashMap에있는 모든 항목에 대한 시간 제한 설정

HashMap<K,V> map = new HashMap<>(); 
void addEntry(K,V) { 
    //set timeout for the key-value pair to say 10 seconds 
    map.put(K,V); 
} 

void actionAfterTimeout(K) { 
    //do something 
    map.remove(K); 
} 

시간 초과가 발생하면 일부 처리를 수행하고지도에서 항목을 제거하고 싶습니다. 어떻게해야합니까?

+2

사소한 작업이 아닙니다. 기존 캐시 API를 사용 해본 적이 있습니까? 대개 시간 초과시에 제거되지 않기 때문에 원하는대로 정확하게 수행 할 수 없습니다 (시간 초과가 발생했음을 감지하고 다음 클라이언트 호출에서 다시 가져 오기). –

답변

2

Timer.schedule(TimerTask task, long delay)을 사용하십시오.

HashMap<K,V> map = new HashMap<>(); 
Timer timer = new Timer(); 
long timeout = 10_000; // milliseconds 

void addEntry(K key, V value) { 
    //set timeout for the key-value pair to say 10 seconds 
    map.put(key, value); 

    timer.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      actionAfterTimeout(key); 
     } 
    }, timeout); 
} 

void actionAfterTimeout(K key) { 
    //do something 
    map.remove(key); 
} 
+0

addEntry() 함수 외부에서 타이머를 생성하면 HashMap에 추가 된 모든 항목에 대해 새 타이머가 시작됩니까? – arpp

+0

원하는 경우 그렇게 할 수 있습니다. – MoienGK

+0

'타이머'가 한 번 생성됩니다. 'addEntry'가 호출 될 때마다 새로운'TimerTask'가 언젠가 미래에 실행되도록 스케쥴 될 것입니다. 'addEntry'가 호출되지 않으면'TimerTasks'가 실행되지 않습니다. 그게 도움이 되나요? – SamC

0

다중 스레드를 사용하지 않으려는 경우이 방법이 유용합니다. 그것은 threadsafe하지 않습니다. 타임 아웃이 발생한 후 맵에 대한 첫 번째 히트에 대한 처리를 수행합니다.

class TimedMap<K, V> 
{ 

    private Map<K, V> map = new HashMap<>(); 
    private Map<K, Long> timerMap = new LinkedHashMap<>(); 
    private static final Long TIMEOUT_IN_MILLIS = 10000; 

    public void addEntry(K key, V value) 
    { 
     checkTimeout(); 
     map.put(key, value); 
     timerMap.remove(key); 
     timerMap.put(key, System.currentTimeInMillis()); 
    } 

    public void getEntry(K key) 
    { 
     checkTimeout(); 
     map.get(key); 
    } 

    private void checkTimeout() 
    { 
     List<K> removals = new LinkedList<>(); 
     for(K key : map.keySet()) 
     { 
      if((System.currentTimeMillis() - 
         timerMap.get(key)) > 
        TIMEOUT_IN_MILLIS) 
      { 
       removals.add(key); 
      } 
      else 
      { 
       break; 
      } 
     } 
     for(K removal : removals) 
     { 
      actionAfterTimeout(key); 
     } 
    } 

    private void actionAfterTimeout(K key) 
    { 
     //do something 
     map.remove(key); 
    } 
}