【踩坑专栏】关于实现异步多线程的一些踩坑
创始人
2024-03-28 06:44:27
0

在实现基于redis的分布式锁的时候,有一项功能,就是通过开启异步线程,对还没有unlock的key进行定时刷新,延长时间。

初始版本是New一个线程start。我们知道New一个线程,用了没多久又抛弃,这种方法非常消耗资源。因此我考虑能不能用线程池的方式,来获得线程。

如何配置一个异步线程池,这个我就不多说了,无非是注入一个线程池的bean,@EnableAsync ,@Async等。这些教程非常多,搜一搜就有了。我这里讲一下我遇到的坑。

由于分布式锁的实现类里,有一些成员变量,如针对线程的指针,计算重入次数的计数等,而这些成员变量是不能共享的,所以肯定是不能直接@Component注册为单例的。那能不能注册为其他的类型呢,我们知道,@Component注解还可以通过value指定scope,
在这里插入图片描述
多例可不可以呢?多例,也就是说每次调用到这个类的时候,就生成一个新的实例过来。这显然是不符合预期的。另外多例还有一个坑,就是由于这个指针是一直被单例对象(如某个@Service的业务层)持有,因此在没有断开引用的情况下,是不会给出新的对象的。也就是说它在单例对象如Service或者Controller中实际上也是单例的。
其实最符合我们预期的,应该是request这种类型,在一次请求中,分布式锁的对象始终是一个,对于不同的request,是给出不同的分布式锁的对象。考虑到上述prototype的问题,request是否有同样的问题还未可知,我想后面尝试着写一个自定义的request类型的scope,看下有没有问题。

好,上述讲完了分布式锁为什么至少要是request类型的,那么接下来,就是遇到的坑了。
如下方式会使@Async失效[1]

异步方法使用static修饰异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类异步方法不能与被调用的异步方法在同一个类中类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象如果使用SpringBoot框架在启动类或配置类中增加@EnableAsync注解

因为分布式锁本身是没有注入spring,它里面的执行异步任务的异步类对象(在分布式锁中为一个成员变量,new出来的),由于也拥有布尔类型的成员变量而无法注入,所以异步会失效变为同步!

当然了,即使异步类能够注入到spring中,但是在以@Autowired的方式注入到分布式锁中,你在new出分布式锁后,debug到分布式锁中,会看到成员变量-异步类为Null。原因我猜测是没有注入spring的类,你new出来后,其中autowired的对象无法生效!

综上所述,问题导致现在分布式锁卡在了这里,似乎使用线程去异步刷新锁的时间是一个不可能完成的任务,除非你舍得用new一个线程然后start的方式去执行线程!问题我会在想想,如果有新的进展我这里会更新,如果有大佬看到了,也请大佬不吝赐教,是否有能够完成这种需求的方案~

参考文章:
[1],springboot 开启一个异步线程

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...