如何保证spring bean中的线程安全
程序员文章站
2022-07-10 22:33:06
...
写在前面:这两天做了一个查询接口,由于查询条件和参数太多,采用了链式操作,链式操作的类是个spring service 的bean,执行查询的过程中需要缓存List HashMap 等线程不安全的对象,怎么办捏?
解决过程:
最终通过检索关键字“spring bean 线程安全”找到了答案:
http://www.cnblogs.com/doit8791/p/4093808.html
经过测试,ThreadLocal 是最高效的解决线程安全问题的方法,使用方法如下:
结论:
需要在同一个线程中调用的对象,
定义时,
初始化时,
获取时,
如果想要每次
-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*后知后觉的分割线-&-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*
今天解决别的问题,突然发现,这个Context就是俗称的上下文类,并且在Activiti,spring等源码中也看到了相关的应用,这东西专门用来处理线程安全问题的,哈哈,终于明白了
解决过程:
最终通过检索关键字“spring bean 线程安全”找到了答案:
http://www.cnblogs.com/doit8791/p/4093808.html
经过测试,ThreadLocal 是最高效的解决线程安全问题的方法,使用方法如下:
@Component public class ProcessInstanceQueryImpl implements ProcessInstanceSampleQuery { /** 这种不是线程安全的对象不要放在service的成员变量中 private Map<String, Object> filtrations = new HashMap<String, Object>(); private Map<String, JSONObject> boMap = new HashMap<String, JSONObject>(); private Map<String, BpBasicInfo> basicInfoMap = new HashMap<String, BpBasicInfo>(); private List<String> businessKeyList = new ArrayList<String>();**/ //创建一个ThreadLocal的类Context来缓存那些每次查询链需要用到的成员变量 private static ThreadLocal<Context> context = new ThreadLocal<Context>(); private static enum RelativeCode { RELATIVE, RELATIVED, MERGE, MERGED, SPLIT, SPLITED }; @Resource private UniversalManager universalManager; //Context类用来缓存那些每次查询链需要用到的成员变量 private static class Context { private BpQuery<?, ?> query; private List<String> boQuerys; private String boFilterHql; private String bpInfoHql; private StringBuilder boHql; private String orderHql; private String sortType; private String queryType; private Context() { boQuerys = new ArrayList<String>(); boFilterHql = "select new com.cayenne.bpm.workbench.model.BpBasicInfoAndBo(bpInfo1,bo) from ${boName} as bo ,BpBasicInfo as bpInfo1 where bo.id=bpInfo1.boId "; bpInfoHql = "and bo.id in(select bpInfo.boId from BpBasicInfo as bpInfo where 1=1"; orderHql = ""; sortType = ""; queryType = ""; boHql = new StringBuilder(" "); } } //每次调用该service进行链式查询时,先初始化查询链,创建一个Context线程安全对象 @Override public ProcessInstanceSampleQuery initProcessInstanceSampleQuery() { //set线程安全的查询对象 signal.set(new Context()); return this; } @Override public ProcessInstanceSampleQuery queryTask(String processDefinitionKey) { //获取线程安全对象,并赋值 signal.get().query = createCandiatesQuery(processDefinitionKey); }
结论:
需要在同一个线程中调用的对象,
定义时,
ThreadLocal<Context> context = new ThreadLocal<Context>();
初始化时,
signal.set(new Context());
获取时,
signal.get();(在未调用set方法之前,都是同一个线程之前set的signal值)
如果想要每次
signal.get();获取的是初始化后的结果,那么定义时写成:
ThreadLocal<Context> context = new ThreadLocal<Context>(){ @Override protected Context initialValue() { return new Context(); } };
-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*后知后觉的分割线-&-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*-&-*
今天解决别的问题,突然发现,这个Context就是俗称的上下文类,并且在Activiti,spring等源码中也看到了相关的应用,这东西专门用来处理线程安全问题的,哈哈,终于明白了
上一篇: 用Appium让Android功能自动化测试飞起来
下一篇: 软件测试必看的5本书
推荐阅读
-
如何获取spring mvc中的拦截器的bean
-
如何获取spring mvc中的拦截器的bean
-
如何保证spring bean中的线程安全
-
如何保证spring bean中的线程安全
-
荐 Java中多线程的使用(超级超级详细)线程安全+线程锁原理解析+保证线程安全的三种方式 (同步代码块+同步方法+lock锁) 5
-
Java 并发编程(四):如何保证对象的线程安全性
-
Spring如何解决单例bean线程不安全的问题
-
Spring中Bean的作用域?单例模式是否是线程安全的?
-
关于资源文件中的字段是如何注入到spring bean中的
-
关于资源文件中的字段是如何注入到spring bean中的