Distributed objects - Redisson Reference Guide
Redisson 的分布式对象允许在分布式系统的多个节点间共享和操作数据,就像操作本地对象一样。下面为你列举几种常见的分布式对象及其使用示例:
1. 分布式锁(RLock)
在分布式环境中,分布式锁可保证同一时间只有一个线程能访问共享资源,避免数据不一致问题。
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.TimeUnit;
public class DistributedLockExample {
public static void main(String[] args) {
// 配置 Redisson 客户端
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 获取分布式锁
RLock lock = redisson.getLock("myLock");
try {
// 尝试获取锁,最多等待 10 秒,持有锁的时间为 30 秒
boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
System.out.println("成功获取锁,开始执行任务");
// 模拟业务操作
Thread.sleep(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放锁
if (lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("任务执行完毕,释放锁");
}
}
// 关闭 Redisson 客户端
redisson.shutdown();
}
}
2. 分布式原子变量(RAtomicLong)
分布式原子变量可在分布式环境中进行原子操作,如递增、递减等。
import org.redisson.Redisson;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class DistributedAtomicLongExample {
public static void main(String[] args) {
// 配置 Redisson 客户端
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 获取分布式原子变量
RAtomicLong atomicLong = redisson.getAtomicLong("myAtomicLong");
// 设置初始值
atomicLong.set(10);
// 原子递增
long newValue = atomicLong.incrementAndGet();
System.out.println("递增后的值: " + newValue);
// 关闭 Redisson 客户端
redisson.shutdown();
}
}
3. 分布式集合(RList、RSet、RMap)
- 分布式列表(RList):类似于 Java 的
List
,可在分布式环境中存储和操作有序元素。
import org.redisson.Redisson;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.Arrays;
public class DistributedListExample {
public static void main(String[] args) {
// 配置 Redisson 客户端
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 获取分布式列表
RList<String> list = redisson.getList("myList");
// 添加元素
list.addAll(Arrays.asList("apple", "banana", "cherry"));
// 打印列表元素
System.out.println("列表元素: " + list);
// 关闭 Redisson 客户端
redisson.shutdown();
}
}
- 分布式集合(RSet):类似于 Java 的
Set
,可在分布式环境中存储唯一元素。
import org.redisson.Redisson;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.Arrays;
public class DistributedSetExample {
public static void main(String[] args) {
// 配置 Redisson 客户端
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 获取分布式集合
RSet<String> set = redisson.getSet("mySet");
// 添加元素
set.addAll(Arrays.asList("apple", "banana", "apple"));
// 打印集合元素
System.out.println("集合元素: " + set);
// 关闭 Redisson 客户端
redisson.shutdown();
}
}
- 分布式映射(RMap):类似于 Java 的
Map
,可在分布式环境中存储键值对。
import org.redisson.Redisson;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class DistributedMapExample {
public static void main(String[] args) {
// 配置 Redisson 客户端
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 获取分布式映射
RMap<String, Integer> map = redisson.getMap("myMap");
// 添加键值对
map.put("apple", 10);
map.put("banana", 20);
// 获取值
Integer value = map.get("apple");
System.out.println("apple 的值: " + value);
// 关闭 Redisson 客户端
redisson.shutdown();
}
}
这些示例展示了 Redisson 分布式对象的基本用法,借助这些分布式对象,你能够轻松实现分布式系统中的数据共享和并发控制。
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.TimeUnit;
public class DistributedLockExample {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getLock("myLock");
try {
// 尝试获取锁,等待10秒,锁的持有时间为30秒
boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
System.out.println("获取到锁,执行临界区代码");
// 模拟业务操作
Thread.sleep(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("释放锁");
}
}
redisson.shutdown();
}
}
2. 分布式信号量semaphore 服务
分布式信号量用于控制对共享资源的并发访问数量,限制同时访问某资源的线程或进程数量。
import org.redisson.Redisson;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DistributedSemaphoreExample {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RSemaphore semaphore = redisson.getSemaphore("mySemaphore");
semaphore.trySetPermits(3); // 设置信号量的许可数量为3
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
executor.submit(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 获取到许可,执行任务");
Thread.sleep(2000);
semaphore.release();
System.out.println(Thread.currentThread().getName() + " 释放许可");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
redisson.shutdown();
}
}
3. 分布式CountDownLatch服务
分布式闭锁允许一个或多个线程等待其他线程完成操作后再继续执行。
import org.redisson.Redisson;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DistributedCountDownLatchExample {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RCountDownLatch latch = redisson.getCountDownLatch("myLatch");
latch.trySetCount(3); // 设置计数器初始值为3
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) {
executor.submit(() -> {
try {
System.out.println(Thread.currentThread().getName() + " 开始执行任务");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " 完成任务");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
try {
latch.await();
System.out.println("所有任务完成,主线程继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
redisson.shutdown();
}
}
4. 分布式远程服务调用
Redisson 支持分布式环境下的远程服务调用,允许不同节点之间相互调用服务方法。
// 定义服务接口
public interface MyRemoteService {
String sayHello(String name);
}
// 服务实现类
public class MyRemoteServiceImpl implements MyRemoteService {
@Override
public String sayHello(String name) {
return "Hello, " + name;
}
}
// 服务调用示例
import org.redisson.Redisson;
import org.redisson.api.RRemoteService;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class DistributedRemoteServiceExample {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RRemoteService remoteService = redisson.getRemoteService();
// 注册服务
remoteService.register(MyRemoteService.class, new MyRemoteServiceImpl());
// 获取服务代理
MyRemoteService service = remoteService.get(MyRemoteService.class);
String result = service.sayHello("John");
System.out.println(result);
redisson.shutdown();
}
}
Redisson 是基于 Redis 实现的 Java 驻内存数据网格,提供了丰富的分布式服务,下面分别介绍联锁、分布式执行任务和红锁。
5. 联锁(MultiLock)
联锁是将多个锁作为一个整体来管理,只有当所有的锁都被成功获取时,才能执行后续操作。这在需要同时锁定多个资源的场景中非常有用。
示例代码
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.TimeUnit;
public class RedissonMultiLockExample {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 获取多个锁
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
RLock lock3 = redisson.getLock("lock3");
// 创建联锁
org.redisson.api.RMultiLock multiLock = redisson.getMultiLock(lock1, lock2, lock3);
try {
// 尝试获取联锁,等待10秒,锁的持有时间为30秒
boolean isLocked = multiLock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
System.out.println("成功获取联锁,执行任务");
// 模拟业务操作
Thread.sleep(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (multiLock.isHeldByCurrentThread()) {
multiLock.unlock();
System.out.println("释放联锁");
}
}
redisson.shutdown();
}
}
代码解释
- 首先,通过 Redisson 客户端获取多个锁实例。
- 然后,使用
redisson.getMultiLock()
方法创建联锁对象,将多个锁实例传入。 - 接着,调用
tryLock()
方法尝试获取联锁,若成功则执行任务。 - 最后,在
finally
块中释放联锁。
6. 分布式执行任务(RExecutorService)
Redisson 的 RExecutorService
允许在分布式环境中执行任务,它类似于 Java 标准库中的 ExecutorService
,但可以将任务分发到不同的节点上执行。
示例代码
import org.redisson.Redisson;
import org.redisson.api.RExecutorService;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
public class RedissonExecutorServiceExample {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 获取分布式执行服务
RExecutorService executorService = redisson.getExecutorService("myExecutor");
// 定义任务
Callable<String> task = () -> {
System.out.println("任务开始执行");
Thread.sleep(3000);
return "任务执行完成";
};
// 提交任务
Future<String> future = executorService.submit(task);
try {
// 获取任务结果
String result = future.get();
System.out.println("任务结果: " + result);
} catch (Exception e) {
e.printStackTrace();
}
redisson.shutdown();
}
}
代码解释
- 先创建 Redisson 客户端并获取
RExecutorService
实例。 - 定义一个实现了
Callable
接口的任务。 - 使用
submit()
方法将任务提交到执行服务中,返回一个Future
对象。 - 调用
future.get()
方法获取任务的执行结果。
7. 红锁(RedLock)
红锁是一种基于多个 Redis 节点实现的分布式锁,它增强了锁的可靠性和可用性,即使部分 Redis 节点出现故障,仍然能保证锁的正常使用。
示例代码
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class RedissonRedLockExample {
public static void main(String[] args) {
// 配置多个 Redis 节点
List<RedissonClient> clients = new ArrayList<>();
Config config1 = new Config();
config1.useSingleServer().setAddress("redis://127.0.0.1:6379");
clients.add(Redisson.create(config1));
Config config2 = new Config();
config2.useSingleServer().setAddress("redis://127.0.0.1:6380");
clients.add(Redisson.create(config2));
Config config3 = new Config();
config3.useSingleServer().setAddress("redis://127.0.0.1:6381");
clients.add(Redisson.create(config3));
// 获取多个锁
List<RLock> locks = new ArrayList<>();
for (RedissonClient client : clients) {
locks.add(client.getLock("redLock"));
}
// 创建红锁
org.redisson.api.RLock redLock = new org.redisson.RedissonRedLock(locks.toArray(new RLock[0]));
try {
// 尝试获取红锁,等待10秒,锁的持有时间为30秒
boolean isLocked = redLock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
System.out.println("成功获取红锁,执行任务");
// 模拟业务操作
Thread.sleep(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (redLock.isHeldByCurrentThread()) {
redLock.unlock();
System.out.println("释放红锁");
}
// 关闭所有客户端
for (RedissonClient client : clients) {
client.shutdown();
}
}
}
}
代码解释
- 首先,配置多个 Redis 节点并创建对应的 Redisson 客户端。
- 然后,从每个客户端获取锁实例,并将这些锁实例放入一个列表中。
- 接着,使用
RedissonRedLock
类创建红锁对象,将锁列表传入。 - 调用
tryLock()
方法尝试获取红锁,若成功则执行任务。 - 最后,在
finally
块中释放红锁并关闭所有客户端。