Java 使用线程监视HashMap更新
使用Java线程监视Java数据结构中的更新的最佳方法是什么?我将通过实现一个可运行的接口来创建一个线程。该线程需要每10分钟睡眠和醒来一次,并检查HashMap是否更新。在Java中实现这一点的最佳方法是什么?Java 使用线程监视HashMap更新,java,multithreading,concurrency,executorservice,Java,Multithreading,Concurrency,Executorservice,使用Java线程监视Java数据结构中的更新的最佳方法是什么?我将通过实现一个可运行的接口来创建一个线程。该线程需要每10分钟睡眠和醒来一次,并检查HashMap是否更新。在Java中实现这一点的最佳方法是什么? 当修改操作通过包装器更新lastModified字段时,非常感谢您的帮助,请创建一个类来包装您的数据结构。当线程唤醒时,只需检查lastModified字段,查看是否需要执行某些操作 大概是这样的: import java.util.Date; import java.util.Has
当修改操作通过包装器更新
lastModified
字段时,非常感谢您的帮助,请创建一个类来包装您的数据结构。当线程唤醒时,只需检查lastModified
字段,查看是否需要执行某些操作
大概是这样的:
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class ModTimeMap<K, V> extends HashMap<K, V> {
private Date lastModified;
public Date getLastModified() {
return lastModified;
}
@Override
public void clear() {
updateLastModified();
super.clear();
}
@Override
public V put(K arg0, V arg1) {
updateLastModified();
return super.put(arg0, arg1);
}
@Override
public void putAll(Map<? extends K, ? extends V> arg0) {
updateLastModified();
super.putAll(arg0);
}
@Override
public V remove(Object arg0) {
updateLastModified();
return super.remove(arg0);
}
private void updateLastModified() {
lastModified = new Date();// now
}
}
import java.util.Date;
导入java.util.HashMap;
导入java.util.Map;
公共类ModTimeMap扩展了HashMap{
上次修改的私人日期;
公共日期getLastModified(){
返回最后修改;
}
@凌驾
公共空间清除(){
updateLastModified();
super.clear();
}
@凌驾
公共V put(K arg0,V arg1){
updateLastModified();
返回super.put(arg0,arg1);
}
@凌驾
公屋空置(Map使用默认的HashMap实现这并不容易:您必须在线程上次看到HashMap时保留一份副本,然后在上次看到的状态和当前状态之间进行深入比较。进一步增加问题的是,该方法无法捕捉到映射更改然后在线醒了
我要做的是子类HashMap并添加一个getLastModified
方法。重写每个修饰符方法(put
,remove
,等等)设置上次修改的时间,然后调用super
实现。然后,线程只需检查新ChangeTrackingHashMap
的修改时间,查看它自上次检查以来是否已更改。最好的方法是完全更改概念。实际上,您希望对但是您想如何检测地图是否已更改?与什么进行比较?与大小进行比较?但是,如果一个条目已删除,而另一个条目已添加,则大小不会因地图更改而更改
可能您想将其与上一次迭代中创建的映射克隆进行比较?但首先,映射可能非常大(例如,1亿个条目)。您必须迭代第一个映射以确保所有项都在第二个映射中,然后迭代第二个映射以检查所有键都在第一个映射中。否则,您将丢失额外的项
我建议>?我建议使用调用常规映射的所有方法的包装器包装任何映射,除了一个:put()
。此方法调用真实映射的put,但也会创建特定条目发生更改的事件。在这种情况下,您将实时收到更改通知,而不是在10分钟内
公共类NotifyableMap实现映射{
私人最终地图;
public NotifyableMap(Map-Map)}{this.Map=Map;}
public V put(K key, V value) {
V oldValue = map.put(key, value);
if (!value.equals(oldValue)) { // TODO: make this check null-safe
// notify listeners here
}
}
// all other methods are trivial
}试试:
ScheduledExecutorService daemon = Executors.newScheduledThreadPool(1);
daemon.scheduleWithFixedDelay(new MyRunnable(myMapToCheck),
10, 10, TimeUnit.MINUTE);
//...
private static class MyRunnable implements Runnable {
private final Map<K, V> lastState;
private final Map<K, V> map;
public MyRunnable(Map<K, V> map) {
this.map = map;
this.lastState = new HashMap<>(map);
}
@Override
public void run() {
// copy to avoid changes before updating lastState
Map<K, V> currentState = new HashMap<>(map);
if(currentState.equals(lastState)) {
System.our.println("No change");
} else {
System.our.println("Change!");
}
lastState.clear();
lastState.putAll(currentState);
}
}
ScheduledExecutorService守护进程=执行者。newScheduledThreadPool(1);
daemon.scheduleWithFixedDelay(新的MyRunnable(myMapToCheck)),
10,10,时间单位(分钟);
//...
私有静态类MyRunnable实现Runnable{
国家私人最终地图;
私人最终地图;
公共MyRunnable(地图){
this.map=map;
this.lastState=新HashMap(map);
}
@凌驾
公开募捐{
//在更新lastState之前复制以避免更改
Map currentState=新的HashMap(Map);
if(currentState.equals(lastState)){
System.our.println(“无变更”);
}否则{
System.our.println(“Change!”);
}
lastState.clear();
lastState.putAll(当前状态);
}
}
似乎您需要一个TimerTask来检查地图是否每10分钟更新一次
private Map map = new HashMap();
private Map lastMapState = new HashMap(map);
private boolean updated = false;
//....
private void startCheckingUpdates() {
// Timers run their tasks in a separate Thread
new Timer().schedule(new TimerTask() {
@Override
public void run() {
checkUpdated();
}
}, 600_000, 600_000);
}
//....
private boolean checkUpdated() {
updated = !map.equals(lastMapState);
lastMapState.clear();
lastMapState.putAll(map);
return updated;
}
这看起来像一个听起来有点格格不入的东西,也许你可以考虑当地图被更新时,哈希图中的一个包装类,它会触发一个改变事件。然后,任何可能为这个事件监听的东西都可以做出相应的反应。HashMap(或ConcurrentHashmap)每隔一段时间就会更新一次。我希望能够创建一个线程,该线程每10分钟唤醒一次,检查HashMap是否有新条目。他仍然必须同步对该映射的访问。写入不能保证在读取之前发生。哦,让我更清楚一点。HashMap是一个单例,因此它不是一个单例新对象是的,如果你想保证线程安全,每个方法都必须同步。如果这是一个问题,我绝对建议你从ConcurrentHashMap中进行子类化。@Dan Smith如果你不能更改正在使用的映射,那么你必须跟踪它的使用,在这个范例中。更难。@DanSmith-使它Singleton
不会从同步角度更改任何内容。如何保证所做的更改(添加的元素)在此线程中可见?这将如何确保之前发生?