【问题标题】:Java singleton on enum and ConcurrentHashMap. Thread-safety issues?枚举和 ConcurrentHashMap 上的 Java 单例。线程安全问题?
【发布时间】:2016-07-16 08:47:53
【问题描述】:

我想将暂时被阻止的用户保留在位于单例中的 HashMap 中:

public enum BlockedUsersRepository {

    REPOSITORY;

    private final ConcurrentMap<String, User> blockedUsers = new ConcurrentHashMap<String, User>();

    /* Static 'instance' method */
    public static BlockedUsersRepository getInstance( ) {
            return REPOSITORY;
    }}

用户在多次尝试输入卡号失败后进入地图。我通过从 User 类启动以下方法来做到这一点:

    public void addBlockedUser(User user) {
            blockedUsers.put(user.getEmail(),user);
    }

    public void removeBlockedUser(User user) {
            blockedUsers.remove(user.getEmail());
    }

问题是:我是否采取了足够的线程安全措施?如何在终端中对地图的并发访问进行建模,以确保它确实有效或失败?这是否是一种合适的方法,因为我担心它很蹩脚,因为单音扮演的角色有点像一个全局变量,可由多个用户实例访问/修改。我是 Java 并发的新手,请您宽容。谢谢。

【问题讨论】:

    标签: java concurrency enums singleton


    【解决方案1】:

    作为单例的枚举是一种创建枚举的线程安全方式。您在 ConcurrentMap 上有 final 表示此时没有问题。

    ConcurrentHashMap 不能被并发写入破坏。

    并发的 addBlockedUser/removeBlockedUser 可能会导致用户被阻止或解除阻止。但是 imo 两个结果都可以,因为您没有限制说用户必须被阻止至少 x 秒才能被阻止。

    可能存在但不是直接线程问题的问题。

    • 您确定电子邮件是唯一的吗?否则,只能同时屏蔽其中一个用户。
    • 您确定电子邮件不为空吗? ConcurrentHashMap 不能处理这种情况,会违反唯一性。
    • 您如何处理有人更改电子邮件的情况?

    【讨论】:

    • 我最关心的是线程安全,其余的并不那么重要,因为它只是一个教育项目。非常感谢您的支持。
    猜你喜欢
    • 1970-01-01
    • 2014-08-13
    • 2014-03-04
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    相关资源
    最近更新 更多