中文文档目录
redisson中文文档目录
分布式对象
java
复制代码
package com.example.redissondemo.test;
import com.example.redissondemo.RedissonDemoApplication;
import com.example.redissondemo.test.domain.Order;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* 测试学习redisson 对象 api
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = RedissonDemoApplication.class)
@Slf4j
public class RedissonObjectExampleTests {
@Autowired
private RedissonClient redissonClient;
/**
* 直接存储对象,无需强制类型转换 (支持异步操作)
*/
@Test
public void bucketTest() {
RBucket<Order> orderBucket = redissonClient.getBucket("myOrder");
System.out.println("init : " + orderBucket.get());
// 设置
orderBucket.set(new Order(10L, "OR001"), 1, TimeUnit.MINUTES);
System.out.println("设置 : " + orderBucket.get());
// 删除
System.out.println("删除状态:" + orderBucket.delete() + "当前" + orderBucket.get());
// 重新设置
orderBucket.set(new Order(10L, "OR001"), 1, TimeUnit.MINUTES);
System.out.println("重新设置 : " + orderBucket.get());
// 如果是or1 改为or2
orderBucket.compareAndSet(new Order(10L, "OR001"), new Order(10L, "OR002"));
System.out.println("存在or1 改为or2 : " + orderBucket.get());
// 如果是or1 改为or3
orderBucket.compareAndSet(new Order(10L, "OR001"), new Order(10L, "OR003"));
System.out.println("存在or1 改为or3 : " + orderBucket.get());
// 存在bucket对象就修改为OR3
orderBucket.setIfExists(new Order(10L, "OR003"), 1, TimeUnit.MINUTES);
System.out.println("存在bucket对象就修改为OR3 : " + orderBucket.get());
orderBucket.isExists();
orderBucket.delete();
}
/**
* 数字操作,计数器 原子类操作 等等 (支持异步操作)
*
* @throws ExecutionException
* @throws InterruptedException
* @throws TimeoutException
*/
@Test
public void numberTest() throws ExecutionException, InterruptedException, TimeoutException {
// 存在精度丢失
RDoubleAdder doubleAdder = redissonClient.getDoubleAdder("doubleAdder");
doubleAdder.add(1.9999);
doubleAdder.add(2.0001);
doubleAdder.add(3.0000000000000001);
RFuture<Double> future = doubleAdder.sumAsync();
Double sum = future.get(1000, TimeUnit.MILLISECONDS);
System.out.println(sum);
doubleAdder.delete();
RLongAdder longAdder = redissonClient.getLongAdder("longAdder");
longAdder.add(100);
longAdder.increment();
longAdder.increment();
long longSum = longAdder.sum();
System.out.println(longSum);
longAdder.delete();
longAdder.destroy();
// 当不再使用整长型累加器对象的时候应该自行手动销毁,如果Redisson对象被关闭(shutdown)了,则不用手动销毁
// 支持CAS设置
RAtomicDouble atomicDouble = redissonClient.getAtomicDouble("atoDouble");
double v = atomicDouble.incrementAndGet();
System.out.println(v);
atomicDouble.compareAndSet(v, 2.0);
System.out.println(atomicDouble.get());
atomicDouble.delete();
RLongAdder atoLong = redissonClient.getLongAdder("atoLong");
atoLong.increment();
System.out.println(atoLong.sum());
atoLong.delete();
}
/**
* 限流*
*/
@Test
public void rateLimiterTest() {
RRateLimiter limiter = redissonClient.getRateLimiter("orderImport");
// 初始化
// 最大流速 = 每1秒钟产生10个令牌
// tryAcquire 尝试获取令牌
// 如果令牌足够 则扣减令牌 返回true
// 如果令牌不够 则不扣减 返回false
// acquire 直接获取令牌 如果获取不到令牌 就阻塞等新的令牌产生
// 如果令牌足够 则扣减对应的令牌
// 如果令牌不够 则扣减令牌数量为0
limiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.HOURS);
boolean b = limiter.tryAcquire(1);
System.out.println(" tryAcquire 1 availablePermits : " + limiter.availablePermits());
b = limiter.tryAcquire(10);
System.out.println(" tryAcquire 10 availablePermits : " + limiter.availablePermits());
limiter.acquire(3);
System.out.println("acquire 3 availablePermits : " + limiter.availablePermits());
new Thread(() -> {
limiter.acquire(2);
System.out.println(" acquire 2 availablePermits : " + limiter.availablePermits());
}).start();
limiter.acquire(7);
System.out.println(" acquire 7 availablePermits : " + limiter.availablePermits());
// long start = System.currentTimeMillis();
limiter.acquire(1);
// System.out.println(System.currentTimeMillis() - start);
System.out.println(" acquire 1 availablePermits : " + limiter.availablePermits());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
limiter.acquire(7);
System.out.println(" acquire 7 availablePermits : " + limiter.availablePermits());
limiter.delete();
}
@Test
public void mapDemo() {
// RMap<String, String> test = redissonClient.getMap("test", MapOptions.defaults());
// test.put("testKey", "testValue");
// test.fastPut("fastTestKey", "testValue");
// String testKey = test.get("testKey");
// test.remove("testKey");
// test.get("testKey");
RBucket<MyBucket> myBucket = redissonClient.getBucket("myBucket");
myBucket.set(new MyBucket(), 1, TimeUnit.MINUTES);
System.out.println(myBucket.get());
myBucket.rename("myBucket1");
RBucket<MyBucket> myBucket1 = redissonClient.getBucket("myBucket");
System.out.println(myBucket1.get());
RBucket<MyBucket> myBucket2 = redissonClient.getBucket("myBucket1");
System.out.println(myBucket2.get());
}
@Data
public static class MyBucket {
private String name = "test";
private int age = 10;
}
}
分布式集合
java
复制代码
package com.example.redissondemo.test;
import com.alibaba.fastjson.JSONObject;
import com.example.redissondemo.RedissonDemoApplication;
import com.example.redissondemo.test.domain.Order;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* 测试学习redisson 集合 api
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = RedissonDemoApplication.class)
@Slf4j
public class RedissonCollectionsExampleTests {
@Autowired
private RedissonClient redissonClient;
/**
* Java对象实现了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。与HashMap不同的是,RMap保持了元素的插入顺序。
* 还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口
*
*/
@Test
public void mapTest() throws ExecutionException, InterruptedException {
String key = "user";
RMap<String, String> map = redissonClient.getMap(key);
map.put("name", "zhangsan");
map.put("age", "18");
String name = map.get("name");
System.out.println ("user name : " + name);
boolean b = map.containsKey("age");
System.out.println("has age ? : " + b);
Set<Map.Entry<String, String>> entries = map.entrySet();
System.out.println(Arrays.toString(entries.toArray()));
map.remove("age");
// fastPut 和 put 的区别就是 put会发回之前该索引位置的值(如果存在) 而fastPut 只会返回插入成功与否
map.fastPut("like", "eat");
System.out.println(JSONObject.toJSONString(map));
// 同理
map.fastRemove("like");
// 异步操作 提高操作效率
RFuture<String> putAsyncFuture = map.putAsync("321","");
RFuture<Boolean> booleanRFuture = map.fastPutAsync("123", "");
putAsyncFuture.get();
booleanRFuture.get();
System.out.println(JSONObject.toJSONString(map));
}
/**
* 多值映射 一对多映射关系的存储
* 基于list set
*/
@Test
public void myMultimapTest(){
// 基于set 基于Set的Multimap不允许一个字段值包含有重复的元素。
RSetMultimap<String, String> map = redissonClient.getSetMultimap("RSetMultimap");
map.put("age", "19");
map.put("age", "20");
map.put("name", "zhangsan");
Set<String> allValues = map.get("age");
System.out.println(allValues);
List<String> newValues = Arrays.asList("17", "16", "15");
Set<String> oldValues = map.replaceValues("age", newValues);
System.out.println(oldValues);
Set<String> removedValues = map.removeAll("age");
System.out.println(removedValues);
map.put("carCount", "2");
Set<Map.Entry<String, String>> entries = map.entries();
System.out.println(JSONObject.toJSONString(entries));
map.delete();
// 基于list 同理 基于List的Multimap在保持插入顺序的同时允许一个字段下包含重复的元素。
redissonClient.getListMultimap("myListMultimap");
// Multimap对象的淘汰机制是通过不同的接口来实现的。它们是RSetMultimapCache接口和RListMultimapCache接口,分别对应的是Set和List的Multimaps。
RListMultimapCache<Object, Object> myListMultimap2 = redissonClient.getListMultimapCache("myListMultimap2");
myListMultimap2.expireKey("2", 10, TimeUnit.MINUTES);
RSetMultimapCache<Object, Object> getSetMultimapCache = redissonClient.getSetMultimapCache("getSetMultimapCache");
getSetMultimapCache.expireKey("2", 10, TimeUnit.MINUTES);
}
/**
* 基于Redis的Redisson的分布式Set结构的RSet Java对象实现了java.util.Set接口。
*/
@Test
public void baseSet(){
RSet<Order> set1 = redissonClient.getSet("anySet");
set1.add(new Order());
set1.remove(new Order());
// 基于Redis的Redisson的分布式RSetCache Java对象在基于RSet的前提下实现了针对单个元素的淘汰机制
/**
* 目前的Redis自身并不支持Set当中的元素淘汰,因此所有过期元素都是通过org.redisson.EvictionScheduler实例来实现定期清理的。
* 为了保证资源的有效利用,每次运行最多清理100个过期元素。
* 任务的启动时间将根据上次实际清理数量自动调整,间隔时间趋于1秒到2小时之间。
* 比如该次清理时删除了100条元素,那么下次执行清理的时间将在1秒以后(最小间隔时间)。
* 一旦该次清理数量少于上次清理数量,时间间隔将增加1.5倍。
*/
RSetCache<Object> set2 = redissonClient.getSetCache("anySet2");
// ttl = 10 seconds
set2.add(new Order(), 10, TimeUnit.SECONDS);
// 基于Redis的Redisson的分布式RSortedSet Java对象实现了java.util.SortedSet接口。在保证元素唯一性的前提下,通过比较器(Comparator)接口实现了对元素的排序。
RSortedSet<Integer> set = redissonClient.getSortedSet("anySet");
set.trySetComparator(Comparator.comparingInt(a -> a)); // 配置元素比较器
set.add(3);
set.add(1);
set.add(2);
set.removeAsync(0);
set.addAsync(5);
}
@Test
public void baseListAndQueue(){
// 基于Redis的Redisson分布式列表(List)结构的RList Java对象在实现了java.util.List接口的同时,确保了元素插入时的顺序。
RList<Order> list = redissonClient.getList("anyList");
list.add(new Order());
Order order = list.get(0);
list.remove(new Order());
// 队列
RQueue<Order> queue1 = redissonClient.getQueue("anyQueue");
// 双端队列(Deque
RDeque<Order> queue2 = redissonClient.getDeque("anyDeque");
// 阻塞队列(Blocking Queue)
RBlockingQueue<Order> queue3= redissonClient.getBlockingQueue("anyQueue");
// 有界阻塞队列(Bounded Blocking Queue)
RBoundedBlockingQueue<Order> queue4 = redissonClient.getBoundedBlockingQueue("anyQueue");
// 延迟队列(Delayed Queue)
// 基于Redis的Redisson分布式延迟队列(Delayed Queue)结构的RDelayedQueue Java对象在实现了RQueue接口的基础上提供了向队列按要求延迟添加项目的功能。
// 该功能可以用来实现消息传送延迟按几何增长或几何衰减的发送策略。
RDelayedQueue<Order> delayedQueue = redissonClient.getDelayedQueue(queue1);
// 优先队列(Priority Queue)
RPriorityQueue<Integer> queue = redissonClient.getPriorityQueue("anyQueue");
}
}
分布式锁
redisson分布式锁学习
java
复制代码
private void redissonDoc() throws InterruptedException {
//1. 普通的可重入锁
RLock lock = redissonClient.getLock("generalLock");
// 拿锁失败时会不停的重试
// 具有Watch Dog 自动延期机制 默认续30s 每隔30/3=10 秒续到30s
lock.lock();
// 尝试拿锁10s后停止重试,返回false
// 具有Watch Dog 自动延期机制 默认续30s
boolean res1 = lock.tryLock(10, TimeUnit.SECONDS);
// 拿锁失败时会不停的重试
// 没有Watch Dog ,10s后自动释放
lock.lock(10, TimeUnit.SECONDS);
// 尝试拿锁100s后停止重试,返回false
// 没有Watch Dog ,10s后自动释放
boolean res2 = lock.tryLock(100, 10, TimeUnit.SECONDS);
//2. 公平锁 保证 Redisson 客户端线程将以其请求的顺序获得锁
RLock fairLock = redissonClient.getFairLock("fairLock");
//3. 读写锁 没错与JDK中ReentrantLock的读写锁效果一样
RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWriteLock");
readWriteLock.readLock().lock();
readWriteLock.writeLock().lock();
}