好用的Redisson
文章目录
- 好用的Redisson
- 介绍
- 如何安装 Redisson
- 如何编译运行 Redisson
- 使用 RList 操作 Redis 列表
- 示例
- 使用 RMap 操作 Redis 哈希
- 示例
- 使用 RLock 实现 Redis 分布式锁
- 示例
- 使用 RAtomicLong 实现 Redis 原子操作
- 示例
- **获取分布式队列**:RedissonClient提供了分布式队列的实现,这可以帮助我们实现消息队列
- **获取分布式发布订阅**:RedissonClient提供了分布式发布订阅的实现,这可以帮助我们实现消息的发布和订阅
- RedissonClient提供了许多方法,以下列举了其中的一些:
介绍
作为 Java 开发人员,我们若想在程序中集成 Redis,必须使用 Redis 的第三方库。而 Redisson 就是用于在 Java 程序中操作 Redis 的库,它使得我们可以在程序中轻松地使用 Redis。Redisson 在 java.util 中常用接口的基础上,为我们提供了一系列具有分布式特性的工具类。
如何安装 Redisson
安装 Redisson 最便捷的方法是使用 Maven 或者 Gradle:
•Maven
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.11.4</version>
</dependency>
•Gradle
compile group: 'org.redisson', name: 'redisson', version: '3.11.4'
目前 Redisson 最新版是 3.11.4,当然你也可以通过搜索 Maven 中央仓库 mvnrepository[1] 来找到 Redisson 的各种版本。
如何编译运行 Redisson
安装 Redisson 后,只需使用 Java 编译器即可编译和运行 Redisson 代码:
javac RedissonExamples.javajava RedissonExamples
使用 RList 操作 Redis 列表
RedissonClient 是一个在 Java 中实现的 in-memory 数据库 Redis 的客户端。它提供了很多高级功能,如分布式对象、分布式锁、分布式集合等。
在 RedissonClient 中,RList
是用于表示 Redis 中的列表数据结构的一个接口。这个接口提供了很多用于操作列表的方法,下面是一些主要的:
- 添加元素:
add(Object o)
: 在列表的末尾添加一个元素。addAll(Collection<?> c)
: 在列表的末尾添加一个集合的所有元素。
- 获取元素:
get(int index)
: 获取指定索引位置的元素。size()
: 获取列表的大小。
- 修改元素:
set(int index, Object element)
: 设置指定索引位置的元素。
- 删除元素:
remove(Object o)
: 移除第一个出现的指定元素。removeAll(Collection<?> c)
: 移除所有出现的指定集合的元素。clear()
: 移除所有元素。
- 检查元素是否存在:
contains(Object o)
: 检查列表是否包含指定的元素。
- 其他操作:
addFirst(Object o)
: 在列表的头部添加一个元素。addLast(Object o)
: 在列表的尾部添加一个元素。removeFirst(Object o)
: 移除第一个出现的指定元素并返回它。removeLast(Object o)
: 移除最后一个出现的指定元素并返回它。move(int sourceIndex, int destIndex)
: 将指定索引位置的元素移动到另一个索引位置。containsAll(Collection<?> c)
: 检查列表是否包含所有指定的元素。indexOf(Object o)
: 返回指定元素在列表中的索引,如果列表不包含该元素则返回 -1。lastIndexOf(Object o)
: 返回指定元素在列表中的最后一个索引,如果列表不包含该元素则返回 -1。
- 排序和查找:
sort(Comparator<? super E> c)
: 根据给定的比较器对列表进行排序。stream()
,parallelStream()
: 返回一个流,以便进行流式处理。
- 其他方法:
RList
还提供了很多其他方法,如获取子列表、获取随机元素等。
这只是 RList
接口中的一部分方法,实际上它还提供了更多的功能和操作。你可以查看 Redisson 的官方文档或源代码来获取更详细的信息和使用示例。
示例
import org.redisson.Redisson;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;public class ListExamples {public static void main(String[] args) {// 默认连接上 127.0.0.1:6379RedissonClient client = Redisson.create();// RList 继承了 java.util.List 接口RList<String> nameList = client.getList("nameList");nameList.clear();nameList.add("bingo");nameList.add("name");nameList.add("https://github.com/demo");nameList.remove(-1);boolean contains = nameList.contains("name");System.out.println("List size: " + nameList.size());System.out.println("Is list contains name 'name': " + contains);nameList.forEach(System.out::println);client.shutdown();}
}
运行上面的代码时,可以获得以下输出:
List size: 2
Is list contains name 'name': true
bingo
yanglbme
使用 RMap 操作 Redis 哈希
RedissonClient中的RMap是一个用于在Redis中存储键值对数据的接口。它提供了许多用于操作映射表的方法,下面是一些主要的:
- 添加键值对:
put(K key, V value)
: 添加或更新一个键值对。putAll(Map<? extends K, ? extends V> m)
: 添加或更新一个映射表中的所有键值对。
- 获取值:
get(Object key)
: 获取指定键的值。get(Object key, V defaultValue)
: 获取指定键的值,如果键不存在则返回默认值。
- 删除键值对:
remove(Object key)
: 删除指定键及其对应的值。
- 检查键是否存在:
containsKey(Object key)
: 检查映射表中是否包含指定的键。containsValue(Object value)
: 检查映射表中是否包含指定的值。
- 获取键的集合:
keySet()
: 返回映射表中所有键的集合。
- 获取值的集合:
values()
: 返回映射表中所有值的集合。
- 获取键值对的集合:
entrySet()
: 返回映射表中所有键值对的集合。
- 其他操作:
putIfAbsent(K key, V value)
: 如果指定键不存在,则添加或更新一个键值对。replace(K key, V value)
: 替换指定键的值。如果键不存在,则不执行任何操作。replace(K key, V oldValue, V newValue)
: 替换与指定旧值匹配的所有键的值。
- 排序和查找:
sort(Comparator<? super K> c)
: 根据给定的比较器对映射表的键进行排序。stream()
,parallelStream()
: 返回一个流,以便进行流式处理。
- 其他方法:
RMap
还提供了很多其他方法,如获取子映射表、获取随机键或值等。
这只是 RMap
接口中的一部分方法,实际上它还提供了更多的功能和操作。你可以查看 Redisson 的官方文档或源代码来获取更详细的信息和使用示例。
示例
import org.redisson.Redisson;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;public class MapExamples {public static void main(String[] args) {// 默认连接上127.0.0.1:6379RedissonClient client = Redisson.create();// RMap 继承了 java.util.concurrent.ConcurrentMap 接口RMap<String, String> map = client.getMap("personalInfo");map.put("name", "name");map.put("address", "adress");map.put("link", "https://link.com/demo");boolean contains = map.containsKey("link");System.out.println("Map size: " + map.size());System.out.println("Is map contains key 'link': " + contains);String value = map.get("name");System.out.println("Value mapped by key 'name': " + value);boolean added = map.putIfAbsent("link", "https://doocs.github.io") == null;System.out.println("Is value mapped by key 'link' added: " + added);client.shutdown();}
}
运行上面的代码时,将会看到以下输出:
Map size: 3
Is map contains key 'link': true
Value mapped by key 'name': name
Is value mapped by key 'link' added: false
使用 RLock 实现 Redis 分布式锁
RedissonClient中的RLock是一个用于在Redis中实现分布式锁的接口。它提供了许多用于操作锁的方法,下面是一些主要的:
- 获取锁:
lock()
: 获取锁,如果锁已被其他客户端持有,则当前客户端会阻塞等待。lock(long leaseTime, TimeUnit unit)
: 获取锁,并设置锁的租用时间。租用时间过后,锁会自动释放。
- 释放锁:
unlock()
: 释放锁。在调用unlock()方法之前,必须确保已经通过调用lock()方法获取了锁。
- 尝试获取锁:
tryLock()
: 尝试获取锁,如果锁未被其他客户端持有,则立即获取锁并返回true,否则返回false。tryLock(long waitTime, long leaseTime, TimeUnit unit)
: 尝试获取锁,如果锁未被其他客户端持有,则等待指定的等待时间后获取锁,并设置锁的租用时间。如果等待时间内无法获取锁,则返回false。
- 重入锁:
lock()
和tryLock()
方法可以用于重入锁,这意味着同一个线程可以多次获取同一个锁,而不会导致死锁。
- 其他操作:
isLocked()
: 检查锁是否被当前客户端持有。isHeldByCurrentThread()
: 检查当前线程是否持有该锁。getHoldCount()
: 返回当前线程对锁的持有次数。getQueueLength()
: 返回等待获取该锁的线程数。
- 过期和自动解锁:
你可以使用expireAfterWrite
和expireAfterAccess
方法为锁设置过期时间。这样,如果一个客户端在一段时间内无法释放锁(例如由于崩溃),那么锁会自动释放。 - 删除和重命名:
使用delete
和rename
方法可以删除或重命名锁。 - 公平性:
通过setFair
方法可以设置锁的公平性。公平锁会按照线程请求锁的顺序来授予锁,而非公平锁则不会保证这个顺序。 - 其他方法:RLock 还提供了很多其他方法,如尝试获取并立即释放锁、获取并增加持有次数等。
这只是 RLock 接口中的一部分方法,实际上它还提供了更多的功能和操作。你可以查看 Redisson 的官方文档或源代码来获取更详细的信息和使用示例。
示例
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;public class LockExamples {public static void main(String[] args) throws InterruptedException {// 默认连接上127.0.0.1:6379RedissonClient client = Redisson.create();// RLock 继承了 java.util.concurrent.locks.Lock 接口RLock lock = client.getLock("lock");lock.lock();System.out.println("lock acquired");Thread t = new Thread(() -> {RLock lock1 = client.getLock("lock");lock1.lock();System.out.println("lock acquired by thread");lock1.unlock();System.out.println("lock released by thread");});t.start();t.join(1000);lock.unlock();System.out.println("lock released");t.join();client.shutdown();}
}
此代码将产生以下输出:
lock acquired
lock released
lock acquired by thread
lock released by thread
使用 RAtomicLong 实现 Redis 原子操作
RedissonClient中的RAtomicLong是一个在Redis中实现的分布式原子长整型数据的接口。它提供了许多用于操作原子长整型数据的方法,下面是一些主要的:
- 增加和减少:
incrementAndGet()
: 原子地增加当前值,并返回增加后的值。decrementAndGet()
: 原子地减少当前值,并返回减少后的值。
- 设置值:
set(long newValue)
: 原子地设置新的值。
- 获取值:
get()
: 获取当前值。
- 比较和交换:
compareAndSet(long expect, long update)
: 原子地比较当前值与期望值,如果相等,则将当前值更新为新值,并返回true,否则不执行任何操作并返回false。
- 其他操作:
addAndGet(long delta)
: 原子地增加当前值,并返回增加后的值。getAndSet(long newValue)
: 原子地设置新的值,并返回旧值。getAndAdd(long delta)
: 原子地增加当前值,并返回增加前的值。
- 获取和设置偏移量:
使用getOffset
和setOffset
方法可以获取和设置偏移量,这可以用于实现原子操作。 - 其他方法:RAtomicLong 还提供了很多其他方法,如尝试获取并立即释放锁、获取并增加持有次数等。
这只是 RAtomicLong 接口中的一部分方法,实际上它还提供了更多的功能和操作。你可以查看 Redisson 的官方文档或源代码来获取更详细的信息和使用示例。
示例
import org.redisson.Redisson;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;public class AtomicLongExamples {public static void main(String[] args) {// 默认连接上127.0.0.1:6379RedissonClient client = Redisson.create();RAtomicLong atomicLong = client.getAtomicLong("myLong");System.out.println("Init value: " + atomicLong.get());atomicLong.incrementAndGet();System.out.println("Current value: " + atomicLong.get());atomicLong.addAndGet(10L);System.out.println("Final value: " + atomicLong.get());client.shutdown();}
}
此代码的输出将是:
Init value: 0
Current value: 1
Final value: 11
获取分布式队列:RedissonClient提供了分布式队列的实现,这可以帮助我们实现消息队列
RedissonClient中的RQueue是一个在Redis中实现的分布式队列的接口。它提供了许多用于操作队列的方法,下面是一些主要的:
- 添加元素:
add(E e)
: 将指定的元素添加到队列的末尾。offer(E e)
: 将指定的元素添加到队列的末尾,如果队列已满,则不执行任何操作。
- 移除元素:
remove()
: 移除并返回队列的头元素。如果队列为空,则不执行任何操作。poll()
: 移除并返回队列的头元素,如果队列为空,则返回null。
- 获取元素:
element()
: 获取但不移除队列的头元素,如果队列为空,则抛出异常。peek()
: 获取但不移除队列的头元素,如果队列为空,则返回null。
- 检查元素:
contains(Object o)
: 检查队列是否包含指定的元素。
- 清空队列:
clear()
: 移除队列中的所有元素。
- 获取队列的大小:
size()
: 返回队列中的元素个数。
- 阻塞队列操作:RQueue 还提供了阻塞版本的获取和移除方法,如
take
和put
,它们可以使当前线程等待直到获取或添加元素为止。 - 其他方法:RQueue 还提供了很多其他方法,如检查队列是否为空、检查是否包含指定元素等。
这只是 RQueue 接口中的一部分方法,实际上它还提供了更多的功能和操作。你可以查看 Redisson 的官方文档或源代码来获取更详细的信息和使用示例。
获取分布式发布订阅:RedissonClient提供了分布式发布订阅的实现,这可以帮助我们实现消息的发布和订阅
RedissonClient
中的 RPubSub
是一个接口,它代表 Redis 的发布/订阅功能。Redis 的发布/订阅模型允许消息的生产者(发布者)发送消息到一个或多个消费者(订阅者)而无需知道它们是谁。在 Redisson 中,RPubSub
提供了一套 API 来实现这种发布/订阅模式。
以下是 RPubSub
提供的主要方法:
- 订阅:
subscribe(String... channelNames)
: 订阅一个或多个频道。当有消息发布到这些频道时,订阅者会收到这些消息。psubscribe(String... patternChannelNames)
: 订阅一个或多个模式频道。模式频道使用模式匹配来过滤消息。
- 取消订阅:
unsubscribe(String... channelNames)
: 取消订阅一个或多个频道。punsubscribe(String... patternChannelNames)
: 取消订阅一个或多个模式频道。
- 发布消息:
- 需要注意的是,
RPubSub
本身并不直接提供发布消息的方法。发布消息通常是通过RTopic
接口来完成的,你可以通过RedissonClient
的getTopic
方法来获取一个RTopic
实例,然后调用其publish
方法来发布消息。
- 需要注意的是,
- 监听消息:
addListener(MessageListener<? super V> listener)
: 添加一个消息监听器,该监听器会在接收到订阅的频道或模式频道的消息时被调用。removeListener(MessageListener<? super V> listener)
: 移除一个消息监听器。
- 其他方法:
getChannelName()
: 获取当前订阅的频道名称(仅适用于单个频道的订阅者)。getPatternChannelName()
: 获取当前订阅的模式频道名称(仅适用于模式频道的订阅者)。
RPubSub
通常与 RTopic
一起使用,RTopic
代表一个可以发布消息的频道。你可以通过 RedissonClient
的 getTopic
方法获取一个 RTopic
实例,并使用它来发布消息。
下面是一个简单的使用示例:
RedissonClient redisson = Redisson.create(); // 获取一个 RTopic 实例
RTopic<String> topic = redisson.getTopic("anyChannel"); // 创建一个 RPubSub 实例并订阅频道
RPubSub<String> pubSub = redisson.getPubSub();
pubSub.addListener(new MessageListener<String>() { @Override public void onMessage(String channel, String message) { System.out.println("Received message: " + message + " from channel: " + channel); }
}); // 订阅频道
pubSub.subscribe("anyChannel"); // 发布消息
topic.publish("Hello, Redis!"); // ... 在某个时刻取消订阅
pubSub.unsubscribe("anyChannel"); // 关闭 Redisson 客户端
redisson.shutdown();
需要注意的是,上面的示例代码中,发布和订阅操作是在同一个进程内完成的,但在实际应用中,发布者和订阅者通常是分布在不同进程或机器上的。此外,订阅操作通常是阻塞的,这意味着订阅者会一直监听频道直到它被取消订阅或程序被终止。在实际应用中,你可能需要在一个单独的线程中处理订阅逻辑。
RedissonClient提供了许多方法,以下列举了其中的一些:
- 创建锁:RedissonClient提供了分布式锁的实现,这可以帮助我们在分布式环境中实现互斥访问。以下是创建和使用锁的示例代码:
RLock lock = redissonClient.getLock("myLock");
lock.lock();
try { // 在这里执行需要互斥的操作
} finally { lock.unlock();
}
- 获取分布式集合:RedissonClient提供了分布式集合的实现,如List、Set、Queue等。以下是获取和使用分布式List的示例代码:
RList<String> list = redissonClient.getList("myList");
list.add("item1");
list.add("item2");
list.add("item3");
- 获取分布式映射表:RedissonClient提供了分布式映射表的实现,这可以帮助我们存储键值对。以下是获取和使用分布式映射表的示例代码:
RMap<String, String> map = redissonClient.getMap("myMap");
map.put("key1", "value1");
map.put("key2", "value2");
String value = map.get("key1");
- 获取分布式哈希表:RedissonClient提供了分布式哈希表的实现,这可以帮助我们存储复杂的数据结构。以下是获取和使用分布式哈希表的示例代码:
RMap<String, Person> map = redissonClient.getMap("myHashTable");
Person person = new Person("John", 30);
map.put("key1", person);
Person value = map.get("key1");
- 获取分布式队列:RedissonClient提供了分布式队列的实现,这可以帮助我们实现消息队列。以下是获取和使用分布式队列的示例代码:
RQueue<String> queue = redissonClient.getQueue("myQueue");
queue.offer("item1");
queue.offer("item2");
String item = queue.poll(); // 获取并移除队列的头元素
- 获取分布式发布订阅:RedissonClient提供了分布式发布订阅的实现,这可以帮助我们实现消息的发布和订阅。以下是使用发布订阅的示例代码:
RPubSub<String, String> pubSub = redissonClient.getPubSub("myPubSub");
pubSub.subscribe("channel1", new MessageListener<String>() { // 订阅一个频道并设置监听器 @Override public void onMessage(String channel, String message) { // 处理消息的逻辑 }
});
pubSub.publish("channel1", "message1"); // 发布一条消息到指定的频道
ring item = queue.poll(); // 获取并移除队列的头元素
1. **获取分布式发布订阅**:RedissonClient提供了分布式发布订阅的实现,这可以帮助我们实现消息的发布和订阅。以下是使用发布订阅的示例代码:```java
RPubSub<String, String> pubSub = redissonClient.getPubSub("myPubSub");
pubSub.subscribe("channel1", new MessageListener<String>() { // 订阅一个频道并设置监听器 @Override public void onMessage(String channel, String message) { // 处理消息的逻辑 }
});
pubSub.publish("channel1", "message1"); // 发布一条消息到指定的频道
以上是RedissonClient中的一些常用方法,实际上RedissonClient还提供了许多其他功能和操作,你可以查看Redisson的官方文档或源代码来获取更详细的信息和使用示例。