List in ConcurrentHashMap

public static ConcurrentHashMap<Integer,Session> USER_SESSIONS...    

Everything works perfectly. But what if the system is allowed to authorize two sessions with the same user ID? Well, these are about two computers sitting under the same account, but different sessions. Tried to do this:

ConcurrentHashMap<Integer,List<Session>> USER_SESSIONS....

...............

private void addUser(Session session){
   List<Session> userSessions = Server.USER_SESSIONS.get(session.mUserId);

   if(userSessions==null){
       userSessions = new List<Session>();
       userSessions.add(session);
       Server.USER_SESSIONS.put(session.getUserId(),userSessions);
   }else{
       userSessions.add(session);
   }
}

private void removeUser(Session session){
  List<Session> userSessions = Server.USER_SESSIONS.get(session.mUserId);

  if(userSessions!=null){
       userSessions.remove(session);
       if(userSessions.size()==0)
       {
           Server.USER_SESSIONS.remove(session.getUserId());
       }
  }
}

.................

private void workWithUsers(int userId){
    for(Session session : Server.USER_SESSIONS.get(userId))
    {
       <do it!>
    }
}

Naturally, all these methods can be called from different threads, and I get List related errors. And this is natural, because although I have a foreach-list session, you can remove removeUser from another thread. What to do? How to make it so - work with the list of all threads The list, having waited while it is busy with the thread, will finish it? Yet done so :)

public static ConcurrentHashMap<Integer,ConcurrentHashMap<Session,Session>> USER_SESSIONS

Since the ConcurrentHashMap stream is safe. But I think this is a crooked decision. Thank you very much for your help!

PS: JRE 1. 6

Sorry for my english.

+4
4

List myList = Collections.synchronizedList(new ArrayList<String>());, CopyOnWriteArrayList.

, , - , . : Collections.synchronizedList

+1

- . , addUser puts. remoeUser.

- ( ). , , .

    private void addUser(Session session) {
    while (true) {
        List<Session> userSessions = Collections.synchronizedList(new ArrayList<Session>());
        List<Session> oldSessions = USER_SESSIONS.putIfAbsent(session.mUserId, userSessions);
        if (oldSessions != null) {
            userSessions = oldSessions;
        }
        userSessions.add(session);

        // want to make sure the map still contains this list and not another
        // so checking references
        // this could be false if the list was removed since the call to putIfAbsent
        if (userSessions == USER_SESSIONS.get(session.mUserId)) {
            break;
        }
    }
}

private void removeUser(Session session) {
    List<Session> userSessions = USER_SESSIONS.get(session.mUserId);
    if (userSessions != null) {
        // make whole operation synchronized to make sure a new session is not added
        // after the check for empty
        synchronized (userSessions) {
            userSessions.remove(session);
            if (userSessions.isEmpty()) {
                USER_SESSIONS.remove(session.mUserId);
            }
        }
    }
}
+1

List myList = Collections.synchronizedList(new ArrayList<String>());
, , CopyOnWriteArrayList, .

0

All Articles