1.我配置了一个redisTemplate
@Configuration
public class RedisConfig {
/**
* 生成操作Redis的bean--RedisTemplate,并将其注入到Spring容器中
*
* @param factory redis连接工厂
* @return 配置好的RedisTemplate
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//为了自己开发方便,一般直接使用<String,Object>
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
//自定义序列化器
Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//Json序列化配置使用ObjectMapper进行转义
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化方式采用jackson
template.setValueSerializer(stringRedisSerializer);
//hash的value序列化方式采用jackson
template.setHashValueSerializer(stringRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
2.定义了一个Redis工具类注入到了Spring容器中
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
public String get(String from,String to,String key){
ValueOperations<String, Object> ops = redisTemplate.opsForValue();
try {
return (String) ops.get(key + ":" + from + ":" + to);
}
catch (Exception e){
e.printStackTrace();
}
return null;
}
public void set(String from,String to,String key,String obj){
ValueOperations<String, Object> ops = redisTemplate.opsForValue();
try {
redisTemplate.multi();
ops.set(key + ":" + from + ":" + to,obj);
redisTemplate.exec();
}
catch (Exception e){
redisTemplate.discard();
}
}
}
3.开了一个线程来执行方法
@Component
@Slf4j
public class AsyncHandShakeTask {
@Autowired
private HandShakeService handShakeService;
@Autowired
private RedisUtil redisUtil;
@Async
public Future<String> doHandShake(String from,String to){
long start = System.currentTimeMillis();
log.info("***************开始加锁***************");
redisUtil.set(from,to,"lock","1");
log.info("***************开始执行握手***************");
handShakeService.doHandShake();
log.info("***************执行握手结束***************");
log.info("***************开始解锁***************");
redisUtil.set(from,to,"lock","0");
long end = System.currentTimeMillis();
log.info("*****任务全部完成,总耗时:" + (end - start) + "毫秒*****");
return new AsyncResult<>("任务全部完成,总耗时:" + (end - start) + "毫秒");
}
@Async
public void testRedis(){
System.out.println("开始设置");
com.platform.security.util.RedisUtil.set("1","2","test","v");
System.out.println("设置完成");
}
}
然后开启线程执行该方法时,就是执行不了,也不是报错,就是执行到
redisUtil.set(from,to,"lock","1");
这句之后,线程自动就退出了。该句也能执行成功。
然后我就十分奇怪,之后,在网上找相关资料时发现一个redisTemplate实例只能占有一个jedis链接。所以感觉可能是这个原因,然后就自己直接使用jedis创建一个连接进行了操作,发现可行。
如果有大佬遇到过同样的情况请告知一二。