我的目标是在代理中实现内部DNS缓存:基本上是保存我的DNS解析度以备将来使用,在需要该解析度之前,请检查缓存中是否具有所需的解析度。为简单起见,我忽略了TTL,而是使用了长达30秒的默认值。我将如何做这样的事情,即使指向正确方向的指针也将不胜感激?我的Java网络代理看起来与http://www.jtmelton.com/2007/11/27/a-simple-multi-threaded-java-http-proxy-server/中的示例非常相似。
这是我为解决这个问题而写的两节课
import java.net.InetAddress;
/**
* Singleton class that holds the ExpiringMap used for DNS Cache
*/
public class DnsCache {
private static ExpiringMap<String, InetAddress> theDnsCache = null;
public static ExpiringMap<String, InetAddress> getInstance() {
if (theDnsCache == null) {
theDnsCache = new ExpiringMap<String, InetAddress>();
}
return theDnsCache;
}
}
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* A HashMap that removes objects after the set TTL
*/
public class ExpiringMap<K, V> implements Map<K, V> {
private final int DEFAULT_TTL = 30;
private final HashMap<K, ScheduledFuture<K>> cacheKeys = new HashMap<K, ScheduledFuture<K>>();
private final HashMap<K, V> theHash = new HashMap<K, V>();
private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
@Override
public int size() {
// TODO Auto-generated method stub
return theHash.size();
}
@Override
public boolean isEmpty() {
return theHash.isEmpty();
}
@Override
public boolean containsKey(Object key) {
return theHash.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return theHash.containsValue(value);
}
/**
* If retrieving an object that already exists in the cache
* we must resets the TTL timer on that item.
*/
@SuppressWarnings("unchecked")
@Override
public V get(final Object key) {
// If item exists in cache, then we cancel and reset the timer on that item
if(cacheKeys.containsKey(key) && cacheKeys.get(key).cancel(false)) {
ScheduledFuture<K> task = executorService.schedule(new Callable<K>() {
@Override
public K call() {
cacheKeys.remove(key);
theHash.remove(key);
return (K) key;
}
}, DEFAULT_TTL, TimeUnit.SECONDS);
cacheKeys.put((K) key, task);
}
return theHash.get(key);
}
/**
* When we add an item to cache we add the key to a map that contains FutureScheduled
* events that will remove the item after TTL
*/
@Override
public V put(final K key, V value) {
ScheduledFuture<K> task = executorService.schedule(new Callable<K>() {
@Override
public K call() {
cacheKeys.remove(key);
theHash.remove(key);
return key;
}
}, DEFAULT_TTL, TimeUnit.SECONDS);
cacheKeys.put(key, task);
return theHash.put(key, value);
}
@Override
public V remove(Object key) {
cacheKeys.remove(key);
return theHash.remove(key);
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
// TODO implement
}
@Override
public void clear() {
cacheKeys.clear();
theHash.clear();
}
@Override
public Set<K> keySet() {
return theHash.keySet();
}
@Override
public Collection<V> values() {
return theHash.values();
}
@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
return theHash.entrySet();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句