05 RedissonPriorityQueue

redisson 基于 org.redisson:redisson-spring-data-27:3.27.2 版本

java 中,操作 redis 一般都会选择 redisson 框架, 我们需要了解常用功能的实现原理, 这次来介绍 RedissonPriorityQueue

使用方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Test
void testPriorityQueue() {
    RPriorityQueue<String> queue = redissonClient.getPriorityQueue("queue");
    queue.clear();
    queue.add("3");
    queue.add("2");
    queue.add("1");
    for (String s : queue.readAll()) {
        System.out.println(s);
    }
}

RedissonPriorityQueue 是通过 list 数据结构来实现的。

add

源码位置: org.redisson.RedissonPriorityQueue#add

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override
public boolean add(V value) {
    // 分布式锁,防止并发
    lock.lock();
    
    try {
        // 通过二分查找插入位置
        BinarySearchResult<V> res = binarySearch(value);
        int index = 0;
        if (res.getIndex() < 0) {
            index = -(res.getIndex() + 1);
        } else {
            index = res.getIndex() + 1;
        }
            
        get(commandExecutor.evalWriteNoRetryAsync(getRawName(), codec, RedisCommands.EVAL_VOID,
           "local len = redis.call('llen', KEYS[1]);"
            + "if tonumber(ARGV[1]) < len then "
                // 获取插入位置的值
                + "local pivot = redis.call('lindex', KEYS[1], ARGV[1]);"
                // 插入值
                + "redis.call('linsert', KEYS[1], 'before', pivot, ARGV[2]);"
                + "return;"
            + "end;"
            + "redis.call('rpush', KEYS[1], ARGV[2]);", 
                Arrays.asList(getRawName()),
                index, encode(value)));
        return true;
    } finally {
        lock.unlock();
    }
}

RedissonPriorityQueueRedissonSortedSet 的内部实现基本是一样的。

0%