ConcurrentSkipListMap how to use it properly

141 views Asked by At

I am using ConcurrentSkipListMap in my code and I want to ensure a method to be concurrent-safe.


    public synchronized UserLogin getOrCreateLogin(Integer userId) {
        // new user
        if (!sessionCache.containsKey(userId)) {
            String sessionKey = sessionKeyPool.getKey();
            sessionCache.putIfAbsent(userId, sessionKey);
            return userSessions.computeIfAbsent(sessionKey, userLogin -> new UserLogin(userId, sessionKey));
        } else { // old user, check session
            String oldSessionKey = sessionCache.get(userId);
            UserLogin old = userSessions.get(oldSessionKey);
            if (!old.isExpired()) return old;
            log.info("Session expired! Create another. User id: " + userId + ", last login: " + old.getStartTime());
            String newKey = sessionKeyPool.getKey();
            UserLogin another = new UserLogin(userId, newKey);
            userSessions.replace(newKey, another);
            sessionCache.replace(userId, newKey);
            return another;
        }
    }

I know that the map atomatically does containsKey(), get and so one. But does not mean the whole block cannot be accessed by two threads at the same time, but at least between line and line the happen-before relationship is guarded(the first thread reaches this line will exit this line first). But, then how to actually use these methods to have a composable and consistent result? How do I lock these lines?

How can I lock to gain the finest granularity without compromising the consistency of output data?

0

There are 0 answers