`
lynnlysh
  • 浏览: 178893 次
  • 性别: Icon_minigender_2
  • 来自: 天津
社区版块
存档分类
最新评论

如何保证spring bean中的线程安全

    博客分类:
  • java
阅读更多
写在前面:这两天做了一个查询接口,由于查询条件和参数太多,采用了链式操作,链式操作的类是个spring  service 的bean,执行查询的过程中需要缓存List HashMap 等线程不安全的对象,怎么办捏?
解决过程:
最终通过检索关键字“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等源码中也看到了相关的应用,这东西专门用来处理线程安全问题的,哈哈,终于明白了
0
0
分享到:
评论

相关推荐

    线程中获取spring 注解bean

    当需要在线程中获取Spring注解的bean时,有几种常见的方法: 1. **ThreadLocal**:Spring提供了一种名为`ThreadLocalTargetSource`的特殊`TargetSource`实现,可以将bean实例绑定到当前线程。这样,每个线程都有其...

    Spring框架bean工具,在多线程环境下手动创建bean

    一个Spring框架的bean工具,可以在多线程环境下手动创建bean。使用时请注意在spring配置文件下加入&lt;bean id="springBeanUtils" class="com.hujin.common.util.SpringBeanUtils"/&gt;

    在非spring注解类中使用spring容器中的bean_普通类中使用yml配置文件中的配置信息

    在大数据采集项目中,这种灵活性非常有用,因为有时我们可能需要在非Spring管理的组件或线程中访问配置信息或依赖的Bean。确保正确初始化和管理`ApplicationContext`以及配置属性,就能在任何地方充分利用Spring的...

    spring在@Bean注解中initMethod调用方法异步

    在Spring框架中,`@Bean`注解是一个关键的组件,用于声明一个方法将返回的对象作为Spring容器中的bean。在`@Bean`中定义`initMethod`属性,可以指定该bean初始化时需要调用的方法。当`initMethod`被设置为异步执行,...

    基于Spring+Ibatis的安全线程实现

    在IT行业中,安全性和线程管理是任何应用开发的核心部分,尤其是在使用Spring和Ibatis这样的流行框架时。本文将深入探讨如何在Spring框架下结合Ibatis实现安全的线程处理,确保多用户并发访问时的数据一致性与系统...

    spring boot注解事务+多线程

    在Spring Boot应用中,事务管理和多线程是两个非常关键的特性,特别是在处理复杂的业务逻辑时。本示例将深入探讨如何使用注解来实现事务控制以及如何在Spring Boot中运用多线程。 首先,让我们关注"注解事务"。在...

    java中spring里实现多线程

    在实际项目中,我们还需要关注线程安全问题,比如同步机制(synchronized关键字、Lock接口)、线程间通信(wait、notify、Condition)以及并发工具类(ConcurrentHashMap、CountDownLatch、CyclicBarrier、Semaphore...

    Quartz注入Spring的Bean

    2. **线程安全**:当多个Job实例并行运行时,确保注入的Bean是线程安全的,或者对并发访问进行了适当的同步控制。 3. **Job实例复用**:Quartz允许Job实例的复用,因此要确保Job类的状态不会在不同调度之间互相干扰...

    spring单例引起的线程安全问题

    总结来说,Spring 中的单例模式虽然方便了对象管理,但如果不注意线程安全问题,可能会导致意料之外的结果。在设计类时,应该根据业务需求谨慎选择实例化策略,并且对于可变状态的单例类,应采取适当的同步措施或改...

    Spring 多线程下注入bean问题详解

    在 Spring 框架中,多线程下注入 Bean 是一个常见的问题。本文将详细介绍 Spring 多线程下注入 Bean 问题,并提供两种解决方案。 问题描述 在多线程环境下,使用 Spring 框架时,可能会遇到 Bean 注入失败的问题。...

    Spring 异步多线程动态任务处理的使用心得

    本文将深入探讨在Spring中如何利用多线程和动态任务来实现异步处理,并分享一些实践心得。 首先,我们要理解Spring的异步处理机制。Spring通过`@Async`注解实现了方法级别的异步执行。当一个带有`@Async`的方法被...

    Spring bean为什么默认是单例

    为了保证线程安全,开发者需要额外的同步机制,如使用`synchronized`关键字或Lock,但这会增加代码的复杂性。相比之下,"prototype"作用域的Bean每次请求都会创建新的实例,避免了线程安全问题,但代价是性能的降低...

    最新面试文档.pdf

    在Spring框架中,Bean的线程安全性是一个常见的面试话题。首先,我们要明确Spring本身并不提供任何内置机制来确保Bean的线程安全。Spring容器只是一个管理Bean生命周期和依赖注入的工具,它并不负责处理线程安全问题...

    Spring并发访问的线程安全性问题.docx

    4. **同步访问**:对于必须在Controller中保存的共享状态,可以使用`synchronized`关键字或者`Collections.synchronizedMap()`来确保线程安全。然而,这通常会导致性能下降,因为线程需要等待其他线程释放锁。 5. *...

    详解Spring中bean的scope以后使用

    需要注意的是,虽然`Singleton`作用域下的Bean在整个容器中是唯一的,但这并不意味着它是线程安全的。开发者需要确保Bean内部的状态管理符合多线程环境的要求。 #### 四、Prototype作用域 **Prototype**作用域下的...

    Spring项目bean基础配置代码

    在Spring框架中,Bean是核心概念,它是Java对象在Spring容器中的实例,通过XML或Java配置来定义。本文将深入探讨Spring项目中的Bean基础配置、别名配置以及作用范围配置。 首先,我们来理解Bean的基础配置。在...

    4 后台使用Spring中的Bean质量评估193210111党涛1

    在Web应用中,如果Bean被设计为单例,并且需要处理多个用户的请求,那么必须确保这些Bean是线程安全的。Spring提供了一些策略来确保Bean的安全性,如使用线程局部变量、同步方法或避免使用共享状态。 其次,最常见...

    HttpClient+ Spring实现多线程

    注意在并发环境中,必须确保HttpClient的线程安全,例如,避免在多个线程之间共享同一个HttpClient实例,而是为每个请求创建新的HttpClient,或者使用连接池来复用连接。 总的来说,HttpClient与Spring的结合使得在...

Global site tag (gtag.js) - Google Analytics