1

我在我的代码中使用 ConcurrentSkipListMap 并且我想确保方法是并发安全的。


    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;
        }
    }

我知道地图会自动执行containsKey()get等等。但并不意味着整个块不能被两个线程同时访问,而是至少在行与行之间保护了happens-before关系(第一个线程到达该行将首先退出该行)。但是,那么如何实际使用这些方法来获得可组合且一致的结果呢?如何锁定这些行?

如何在不影响输出数据一致性的情况下锁定以获得最精细的粒度?

4

0 回答 0