我有一个关于 HashMap 同步的问题。背景是我正在尝试实现一种简单的蛮力检测方法。我将使用一个以用户名作为键的映射,用于保存用户登录尝试失败的次数。如果登录失败,我想做这样的事情:
Integer failedAmount = myMap.get("username");
if (failedAmount == null) {
myMap.put("username", 1);
} else {
failedAmount++;
if (failedAmount >= THRESHOLD) {
// possible brute force detected! alert admin / slow down login
// / or whatever
}
myMap.put("username", failedAmount);
}
我现在想到的机制非常简单:我会整天跟踪它并在午夜或类似的时候清除()HashMap。
所以我的问题是: 我可以为此使用的最好/最快的 Map 实现是什么?我需要一个完全同步的 Map (Collections.sychronizedMap()) 还是一个 ConcurrentHashMap 就足够了?或者甚至只是一个普通的 HashMap?我想如果漏掉了一些增量,这不是什么大问题?
最佳答案
我会结合使用 ConcurrentHashMap
和 AtomicInteger
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html .
使用 AtomicInteger
不会帮助您进行比较,但会帮助您保持数字准确 - 无需分两步执行++ 和 put。
在 ConcurrentHashMap
上,我会使用 putIfAbsent
方法,这将消除您的第一个 if
条件。
AtomicInteger failedAmount = new AtomicInteger(0);
failedAmount = myMap.putIfAbsent("username", failedAmount);
if (failedAmount.incrementAndGet() >= THRESHOLD) {
// possible brute force detected! alert admin / slow down login
// / or whatever
}
关于java - Map 的 HashMap 同步与增值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9534714/