Der Mainstream-Weg, dieses Problem anzugehen, wäre die Verwendung eines Timer-Threads, um Ihren Cache in festgelegten Intervallen zu aktualisieren. Da Sie jedoch keine neuen Threads erstellen müssen, ist eine mögliche Implementierung, an die ich denke, die eines pseudo-zeitgesteuerten Cache-Refreshs. Grundsätzlich würde ich Überprüfungen in den Cache-Zugriffsmethoden (set und get Methoden) einfügen und jedes Mal, wenn Clients diese Methoden verwenden, überprüfen, ob der Cache aktualisiert werden muss, bevor die Set- oder Get-Aktion durchgeführt wird. Das ist die grobe Idee:
class YourCache {
// hält den Zeitpunkt des letzten Cache-Refreshs in Millisekunden
private volatile long lastRefreshDate;
// gibt an, dass der Cache im Moment Einträge aktualisiert
private volatile boolean cacheCurrentlyRefreshing;
private Karte Cache = // Ihre gleichzeitige Karte Cache...
public void put(Object key, Object element) {
if (cacheNeedsRefresh()) {
refresh();
}
Map.put(key, Element);
}
public Object get(Object key) {
if (cacheNeedsRefresh()) {
refresh();
}
return Map.get(key);
}
private boolean cacheNeedsRefresh() {
// Stellen Sie sicher, dass der Cache nicht gerade von einem anderen Thread aktualisiert wird.
if (cacheCurrentlyRefreshing) {
return false;
}
return (now - lastRefreshDate) >= REFRESH_INTERVAL;
}
private void refresh() {
// Stellen Sie sicher, dass der Cache zwischen CacheNeedsRefresh()
// und Refresh() nicht von einem anderen Thread zu aktualisieren beginnt.
if (cacheCurrentlyRefreshing) {
return;
}
// Signal an andere Threads, dass der Cache im Moment aktualisiert wird.
cacheCurrentlyRefreshing = true;
try {
// aktualisieren Sie hier den Cache-Inhalt
} finally {
// setzen Sie den lastRefreshDate und signalisieren Sie, dass der Cache fertig ist
// aktualisieren Sie andere Threads.
lastRefreshDate = System.currentTimeMillis();
cahceCurrentlyRefreshing = false;
}
}
}
Persönlich würde ich es nicht so machen, aber wenn Sie keine Timer-Threads erstellen möchten oder können, könnte dies eine Option für Sie sein.
Beachten Sie, dass obwohl diese Implementierung das Sperren vermeidet, sie immer noch anfällig für doppelte Aktualisierungen aufgrund von Rennereignissen ist. Wenn dies für Ihre Anforderungen in Ordnung ist, sollte es kein Problem sein. Wenn Sie jedoch strengere Anforderungen haben, müssen Sie Sperren setzen, um die Threads ordnungsgemäß zu synchronisieren und Rennereignisse zu vermeiden.