2016-07-16 109 views
3

我想保持暫時受阻用戶位於一個單一個HashMap:枚舉上的Java單例和ConcurrentHashMap。線程安全問題?

public enum BlockedUsersRepository { 

    REPOSITORY; 

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

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

一個用戶進入地圖的一些不成功的嘗試輸入卡號後。我這樣做,通過推出從用戶類以下方法:

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

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

的問題是:我該承擔線程安全ENOUGH措施?我如何模擬在終端中對地圖的併發訪問,以確保它真正起作用或失敗?這是否是一種合適的方法,因爲我擔心這是一種蹩腳的行爲,因爲singlet的作用就像是一個全局變量,可以被許多User實例訪問/修改。我對Java的併發性感到陌生,並要求你寬容。謝謝。

回答

2

作爲單例的枚舉是創建一個的線程安全方式。 ConcurrentMap上有final,這意味着沒有問題。

ConcurrentHashMap不能被併發寫入中斷。

併發addBlockedUser/removeBlockedUser可能會導致用戶被阻止或解除阻止。但是,由於您沒有約束條件,說用戶必須被阻止至少x秒才能被禁止,所以兩種結果都可以。

可能存在的問題,但不直接引起問題。

  • 你確定電子郵件是唯一的嗎?否則,這些用戶中只有一個可以同時被阻止。
  • 您是否確定電子郵件不爲空? ConcurrentHashMap不能處理這種情況,並且會違反唯一性。
  • 你如何處理有人更換電子郵件的情況?
+0

我最擔心的是線程安全問題,其他問題並不重要,因爲它只是一個教育項目。非常感謝支持。 –