首页 > 解决方案 > 为什么 reddison ExpirationEntry 使用 LinkedHashMap 来保存 Thr​​ead?

问题描述

Reddison watchDog 策略使用 timerTask 增加 key 过期时间,同时设置锁成功

private void renewExpiration() {
    ExpirationEntry ee = EXPIRATION_RENEWAL_MAP.get(getEntryName());
    if (ee == null) {
        return;
    }
    
    Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
        @Override
        public void run(Timeout timeout) throws Exception {
            ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
            if (ent == null) {
                return;
            }
            Long threadId = ent.getFirstThreadId();
            if (threadId == null) {
                return;
            }
            
            RFuture<Boolean> future = renewExpirationAsync(threadId);
            ......
   }

}

首先使用entryName获取 ExpirationEntry 对象。同一个entryName,其他线程取不到key,因为locked(ps:同一个线程可以get和counter++),那么为什么只有一个线程的时候用LinkedHashMap来保存线程呢?

公共静态类 ExpirationEntry {

    private final Map<Long, Integer> threadIds = new LinkedHashMap<>();
    private volatile Timeout timeout;

    public ExpirationEntry() {
        super();
    }

    public synchronized void addThreadId(long threadId) {
        Integer counter = threadIds.get(threadId);
        if (counter == null) {
            counter = 1;
        } else {
            counter++;
        }
        threadIds.put(threadId, counter);
    }

}

也许就像这样:

public static class ExpirationEntry {
    private volatile Timeout timeout;
    private Long threadId;
    private int counter;

    public synchronized void addThread(Long threadId) {
        if (this.threadId.equals(threadId)) {
            counter ++;
        }
    }
}

我将不胜感激,谢谢

标签: redisson

解决方案


推荐阅读