1.pom配置 添加依赖
4.0.0 org.springframework.boot spring-boot-starter-parent2.6.7 com.sun redis0.0.1-SNAPSHOT redis 1.8 org.springframework.boot spring-boot-starter-web
lombok
spring-boot-starter-data-redis
2.编写redisTemplate 配置类
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate
RedisTemplate
// 配置连接工厂
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jacksonSerial =new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSerial.setObjectMapper(om);
// 值采用json序列化
template.setValueSerializer(jacksonSerial);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSerial);
template.afterPropertiesSet();
return template;
}
}
3.添加yml配置
spring: redis: host: 192.168.113.129 port: 6379 timeout: 3000 pool: max-wait: 30000 max-active: 100 max-idle: 20 min-idle: 0
4.分布式锁的实现
@Service @Slf4j public class RedisLock { @Autowired private RedisTemplateredisTemplate; private ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100));
/** * 加锁 * * @param key * @param userId * @param timeOut * @return */ public boolean lock(String key, String userId, long timeOut) { boolean success = redisTemplate.opsForValue().setIfAbsent(key, userId, timeOut, TimeUnit.SECONDS); if (!success) { log.error("key:{},userId:{} get lock failer ", key, userId); return false; } try { renewExpiration(key,userId, timeOut); Thread.sleep(20000); return true; } catch (Exception e) { log.error("lock occur error:{}", e); return false; } finally { releaseLock(key, userId); } } /** * 续命 *** 作 * * @param key * @param timeOut */ private void renewExpiration(String key,String userId, long timeOut) { threadPool.execute(() -> { Long currentTimeMills = System.currentTimeMillis(); System.out.println("开始:" + LocalDateTime.now() + " ,timeOut:" + timeOut); while (true) { if (redisTemplate.hasKey(key) && userId.equals(redisTemplate.opsForValue().get(key))) { Long cost = System.currentTimeMillis() - currentTimeMills; if (cost > timeOut * 1000 / 2) { currentTimeMills = System.currentTimeMillis(); redisTemplate.expire(key, timeOut, TimeUnit.SECONDS); System.out.println("进行中:" + LocalDateTime.now() + " ,timeOut:" + timeOut); } } else { break; } } }); }
/** * 释放锁 * * @param key * @param userId */ private void releaseLock(String key, String userId) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; DefaultRedisScriptredisScript = new DefaultRedisScript(script, Long.class); Long result2 = redisTemplate.execute(redisScript, Arrays.asList(key), userId); System.out.println("result2=" + result2); } }
结果:
2022-04-25 00:41:15.089 INFO 16644 --- [nio-6012-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
开始:2022-04-25T00:41:16.361 ,timeOut:10
进行中:2022-04-25T00:41:21.358 ,timeOut:10
进行中:2022-04-25T00:41:26.364 ,timeOut:10
进行中:2022-04-25T00:41:31.362 ,timeOut:10
进行中:2022-04-25T00:41:36.363 ,timeOut:10
result2=1
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)