使用Java线程监控Java数据结构中的更新的最佳方法是什么?我将通过实现Runnable接口来创建一个线程。该线程需要每10分钟睡眠和唤醒,并检查HashMap是否更新。在Java中执行此操作的最佳方法是什么? 任何帮助,非常感谢
答案 0 :(得分:1)
好像你想让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;
}
答案 1 :(得分:0)
创建一个类来包装您的数据结构,当修改操作通过您的包装器更新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
}
}
我建议公开一些构造函数并添加一个序列版本ID,但这会让你有机会尝试。
答案 2 :(得分:0)
使用默认的HashMap实现,这不是一件容易的事情:您必须像上次查看的那样保留HashMap的副本,然后在最后看到的状态之间进行深入比较和目前的状态。进一步增加问题的方法是,该方法不会捕获地图发生变化的情况,然后在线程醒来之前进行更改。
我要做的是将HashMap子类化并添加getLastModified
方法。覆盖每个修饰符方法(put
,remove
等)并设置lastModified时间,然后调用super
实现。然后,您的主题可以简单地检查新ChangeTrackingHashMap
的修改时间,以查看自上次检查后它是否已更改。
答案 3 :(得分:0)
最好的方法是彻底改变这个概念。您实际上想要定期轮询您的地图。但是,您如何检测地图已更改?比较什么?有尺寸吗?但如果删除了一个条目而添加了其他条目,那么map的大小不会改变。
可能你想比较你在上一次迭代中创建的地图的克隆?但首先,地图可能非常大(例如,可以说有1亿个条目)。您必须迭代第一个映射以确保所有条目都在第二个映射中,然后迭代第二个映射以检查所有键是否在第一个映射中。否则你会错过额外的参赛作品。
我建议什么&gt;?我建议使用包装器来包装任何地图,该包装器调用常规地图的所有方法,除了一个:put()
。此方法调用您的真实地图的放置,但也会创建特定条目更改的事件。在这种情况下,您将实时获得更改通知,而不是10分钟。
公共类NotifyableMap实现Map { 私人决赛地图; 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
}
答案 4 :(得分:0)
尝试:
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);
}
}