这里可能没有问题,具体取决于您在地图中存储的确切内容。您的代码对我来说看起来有点奇怪,因为您似乎保存了“服务器未激活的持续时间”。
我记录该数据的第一个想法是存储“服务器处于活动状态的最新时间戳”。然后您的代码将如下所示:
package so3950354;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ServerManager {
private final ConcurrentMap<Server, Long> lastActive = new ConcurrentHashMap<Server, Long>();
/** May be overridden by a special method for testing. */
protected long now() {
return System.currentTimeMillis();
}
public void markActive(Server server) {
lastActive.put(server, Long.valueOf(now()));
}
public void removeInactive(long timeoutMillis) {
final long now = now();
Iterator<Map.Entry<Server, Long>> it = lastActive.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<Server, Long> entry = it.next();
final long backThen = entry.getValue().longValue();
/*
* Even if some other code updates the timestamp of this server now,
* the server had timed out at some point in time, so it may be
* removed. It's bad luck, but impossible to avoid.
*/
if (now - backThen >= timeoutMillis) {
it.remove();
}
}
}
static class Server {
}
}
如果您真的想避免在调用markActive
期间没有任何代码调用removeInactive
,则无法绕过显式锁定。你可能想要的是:
markActive
允许并发调用。
- 期间
markActive
不允许打电话removeInactive
。
- 期间
removeInactive
不允许打电话markActive
。
这看起来像是 a 的典型场景ReadWriteLock
,其中markActive
“读取”操作removeInactive
是“写入”操作。