SpringBoot整合redisTemplate时,多线程无法操作

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创建一个连接进行了操作,发现可行。
如果有大佬遇到过同样的情况请告知一二。

Spring Boot中,可以使用@Scheduled注解来实现定任务,可以结合@Async注解来实现多线程异步。 首先,需要在启动类上添加@EnableAsync注解,开启异步支持。然后在要执行异步任务的方法上添加@Async注解。 接下来,可以使用Java中的Executor框架来创建线程池,用于执行异步任务。可以在应用程序中创建一个线程池,并使用@Async注解将任务提交给线程池执行。 下面是一个示例代码: ```java @Configuration @EnableAsync public class AsyncConfig { @Bean(name = "taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(30); executor.setThreadNamePrefix("MyAsyncThread-"); executor.initialize(); return executor; } } @Service public class MyService { @Async("taskExecutor") @Scheduled(cron = "0 0 12 * * ?") //每天中午12点执行 public void myAsyncTask() { //异步任务内容 } } ``` 在上面的示例中,我们创建了一个名为“taskExecutor”的线程池,并将其注入到MyService中的myAsyncTask方法中。该方法使用@Async注解来指示它应该在异步线程中执行。@Scheduled注解指定了任务执行的间。 需要注意的是,@Async注解只有在调用该方法的类通过Spring容器进行管理才会生效。如果通过new关键字手动创建对象,@Async注解将不起作用。 希望这可以帮助你完成Spring Boot任务整合多线程异步的实现。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值