1.RedisTemplate使用Scan
@Component
public class ScanDemo {
@Autowired
private StringRedisTemplate redisTemplate;
public void test() {
for (int i = 0; i cursor = redisTemplate.scan(scanOptions);
while (cursor.hasNext()){
System.out.println(cursor.next());
}
cursor.close();
}
}
2.lua脚本操作Redis
一次扣减一个商品库存
@Component
public class LuaDemo {
@Autowired
private StringRedisTemplate redisTemplate;
public void test() {
List keys = new ArrayList();
keys.add("yanjie007");
String lua = "return redis.call('set',KEYS[1],ARGV[1])";
RedisScript redisScript= RedisScript.of(lua,String.class);
String shuai = stringRedisTemplate.execute(redisScript, keys, "今天真帅");
System.out.println(shuai);
}
}
//扣减库存
@Test
void test2() throws IOException {
valueOperations.set(key,15L);
StringBuilder sb = new StringBuilder();
sb.append(" local key = KEYS[1] ");
sb.append(" local qty = ARGV[1] ");
sb.append(" local redis_qty = redis.call('get',key) ");
sb.append(" if tonumber(redis_qty) >= tonumber(qty) then ");
sb.append(" redis.call('decrby',key,qty) ");
sb.append(" return -1 ");
sb.append(" else ");
sb.append(" return tonumber(redis_qty) "); // 0, 1,2,3 ....
sb.append(" end ");
sb.append(" ");
RedisScript script = RedisScript.of(sb.toString(),Long.class);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 1; i {
int needQty = RandomUtil.randomInt(1, 5);
Long qty = stringRedisTemplate.execute(script, CollUtil.newArrayList(key), needQty+"");
if(qty.intValue() == -1 ){
System.out.println("线程"+ finalI +"扣减成功,需求量是:"+needQty);
} else {
System.out.println("线程"+ finalI +"扣减失败,当前库存变量是:"+qty);
}
});
}
System.in.read();
}
一次扣减多个商品的库存
void test4() {
StringBuilder sb = new StringBuilder();
sb.append(" local table = {} "); // 你要扣减的key :product.1
sb.append(" local values = redis.call('mget', unpack(KEYS) )"); // [product.1,product.2] => product.1 product.2
sb.append(" for i = 1, #KEYS do ");
sb.append(" if tonumber(ARGV[i]) > tonumber(values[i]) then ");
sb.append(" table[#table + 1] = KEYS[i] .. '=' .. values[i] "); // product.1=23
sb.append(" end ");
sb.append(" end ");
sb.append(" if #table > 0 then ");
sb.append(" return table ");
sb.append(" end ");
sb.append(" for i = 1 , #KEYS do ");
sb.append(" redis.call('decrby',KEYS[i],ARGV[i]) ");
sb.append(" end ");
sb.append(" return {} ");
RedisScript luaScript = RedisScript.of(sb.toString(), List.class);
List stockProducts = new ArrayList();
stockProducts.add(new StockProduct(5,1));
stockProducts.add(new StockProduct(4,2));
List keys = stockProducts.stream().map(it -> "product." + it.getId()).collect(Collectors.toList());
Object[] qtys = stockProducts.stream().map(it -> it.getQty() + "").toArray();
List list = stringRedisTemplate.execute(luaScript,
keys,
qtys);
if(list.isEmpty()){
System.out.println("库存冻结成功");
} else {
for (String key_qty : list) {
String[] split = key_qty.split("=");
System.out.println(split[0] + "库存不足,剩余库存量:" + split[1]);
}
}
ThreadUtil.safeSleep(3000);
}
3.模拟多线程并发使用Decrby
@Component
public class DecrByDemo {
@Resource(name = "redisTemplate")
private ValueOperations valueOperations;
private static final String key = "product.01";
public void test() throws InterruptedException {
valueOperations.set(key, 5);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i {
Integer value = valueOperations.get(key);
if (value >= 1) {
valueOperations.set(key, value - 1);
System.out.println(StrUtil.format("线程{} -> 扣减成功", Thread.currentThread().getName()));
} else {
System.out.println(StrUtil.format("线程{} -> 扣减失败", Thread.currentThread().getName()));
}
});
}
Thread.sleep(10*1000);
}
public void test2() throws InterruptedException {
valueOperations.set(key, 5);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i {
Long value = valueOperations.服务器托管decrement(key);
if (value >= 0) {
System.out.println(StrUtil.format("线程{} -> 扣减成功,剩余库存{}", Thread.currentThread().getName(),value));
} else {
System.out.println(StrUtil.format("线程{} -> 扣减失败", Thread.currentThread().getName()));
}
});
}
Thread.sleep(10*1000);
}
}
4.模拟多线程并发获取分布式锁SetNX
@Component
public class SetNxDemo {
@Resource(name = "redisTemplate")
private ValueOperations valueOperations;
private static final String key = "product.1";
public void test() throws InterruptedException {
//出入库场景 商品1
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i =1; i{
// 获取分布式锁
while (true){
Boolean b = valueOperations.setIfAbsent("product.1", "IO202303170929,"+ DateUtil.now());
if(b){
System.out.println(Thread.currentThread().getName() + " 获取到了分布式锁" );
ThreadUtil.safeSleep(5000); //模拟业务操作
stringRedisTemplate.delete("product.1");
break;
} else {
System.out.println(Thread.currentThread().getName() + " 获取锁失败" );
ThreadUtil.safeSleep(2000);
}
}
});
}
System.in.read();
}
}
5.BitMap模拟在线统计
@Component
public class BitMapDemo {
@Resource(name = "redisTemplate")
private ValueOperations valueOperations;
@Autowired
private StringRedisTemplate redisTemplate;
private static final int user01 = 1;
private static final int user02 = 2;
private static final int user03 = 3;
private static String key20220601 = "20200601";
private static String key20220602 = "20200602";
private static String key20220603 = "20200603";
private static String saveKey = "20200601#20200602#20200603";
public void test() {
valueOperations.setBit(key20220601, user01, true);
valueOperations.setBit(key20220601, user02, true);
valueOperations.setBit(key20220602, user02, true);
valueOperations.setBit(key20220603, user01, true);
服务器托管 valueOperations.setBit(key20220603, user03, true);
//1. 一直在线人数统计
//2. 时间段活跃用户
RedisCallback callback = connection -> {
return connection.bitOp(RedisStringCommands.BitOperation.AND, saveKey.getBytes(),
key20220601.getBytes(), key20220602.getBytes(), key20220603.getBytes());
};
Long value = redisTemplate.execute(callback);
RedisCallback callback2 = connection -> {
return connection.bitCount(saveKey.getBytes());
};
Long value2 = redisTemplate.execute(callback2);
System.out.println(value2);
}
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
app端文章搜索 1) 今日内容介绍 1.1)App端搜索-效果图 1.2)今日内容 文章搜索 ElasticSearch环境搭建 索引库创建 文章搜索多条件复合查询 索引数据同步 搜索历史记录 Mongodb环境搭建 异步保存搜索历史 查看搜索历史列表 删除…