java - Map 的 HashMap 同步与增值

标签 java synchronization synchronized

我有一个关于 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?我想如果漏掉了一些增量,这不是什么大问题?

最佳答案

我会结合使用 ConcurrentHashMapAtomicInteger 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/

相关文章:

java - 将单个元素检入具有多列的 ArrayList

java - 触摸 ARM 上的 JavaFX(Java 1.0.8-b123,VM 25.0-b70)

java - EhCache @Cacheable 同步时抛出异常

objective-c - 建议 : Best way to sync sqllite ios to web

Kotlin - 从两个线程访问集合时如何锁定集合

ios - 在iOS中@synchronized一次有2种方法吗?

java - 给定一个 org.w3c.dom.Element,如何在给定的 xpath 字符串中找到一个元素?

java - 使用正则表达式,如何获取下面的代码名称和长度值?

mysql - RDS 和 pt-table-sync。表无法同步。如何解决这个问题?

java - 如何正确使用synchronized?