Spring服务中的私有方法实现类线程安全

时间:2014-08-22 04:12:24

标签: multithreading spring

我在使用Spring框架的项目中获得了一项服务。

public class MyServiceImpl implements IMyService {
    public MyObject foo(SomeObject obj) {
       MyObject myobj = this.mapToMyObject(obj);
       myobj.setLastUpdatedDate(new Date());
       return myobj;
    }

    private MyObject mapToMyObject(SomeObject obj){
       MyObject myojb = new MyObject();
       ConvertUtils.register(new MyNullConvertor(), String.class);
       ConvertUtils.register(new StringConvertorForDateType(), Date.class);
       BeanUtils.copyProperties(myojb , obj);
       ConvertUtils.deregister(Date.class);
       return myojb;
    }
}

然后我有一个类在多线程中调用foo();

出现了问题。在某些线程中,我在调用

时出错

BeanUtils.copyProperties(myojb , obj);

说无法调用com.my.MyObject.setStartDate - java.lang.ClassCastException@2da93171

显然,这是由ConvertUtils.deregister(Date.class)引起的,BeanUtils.copyProperties(myojb , obj);应该在BeanUtils.copyProperties(myojb , obj);之后调用。

看起来其中一个线程取消注册Date类,而另一个线程即将调用{{1}}。

所以我的问题是如何使私有方法mapToMyObject()线程安全?

或者只是在私有方法中使用时,简单地使BeanUtils线程安全。

如果我以这种方式保存代码,但问题仍然存在,而是在sevlet中调用这个foo()方法吗?如果许多sevlets同时调用,那么这也是一个多线程的情况吗?

2 个答案:

答案 0 :(得分:4)

修改:已删除已同步的关键字,因为它不是必需的,请参阅下面的评论。

不使用BeanUtils类中的静态方法,而是使用私有BeanUtilsBean实例(http://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/BeanUtilsBean.html)。这样,每次调用方法时都不需要注册/取消注册转换器。

public class MyServiceImpl implements IMyService {
    private final BeanUtilsBean beanUtilsBean = createBeanUtilsBean();

    private static BeanUtilsBean createBeanUtilsBean() {
        ConvertUtilsBean convertUtilsBean = new ConvertUtils();
        convertUtilsBean.register(new MyNullConvertor(), String.class);
        convertUtilsBean.register(new StringConvertorForDateType(), Date.class);
        BeanUtilsBean beanUtilsBean = new BeanUtilsBean(convertUtilsBean);
        return beanUtilsBean;
    }

    public MyObject foo(SomeObject obj) {
       MyObject myobj = this.mapToMyObject(obj);
       myobj.setLastUpdatedDate(new Date());
       return myobj;
    }

    private MyObject mapToMyObject(SomeObject obj){        
        MyObject myojb = new MyObject();      
        beanUtilsBean.copyProperties(myojb , obj);
        return myojb;
    }
}

答案 1 :(得分:0)

将同步块添加到代码的敏感部分或同步方法:

http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html