当前位置: 代码迷 >> J2EE >> spring 与多线程解决方法
  详细解决方案

spring 与多线程解决方法

热度:82   发布时间:2016-04-17 22:59:24.0
spring 与多线程
大家都知道spring中配置的Bean每人是单例模式. 也就是说一个bean只有一个实例存在.
 如果多个其它的bean(比如beanA, beanB),都引用了一个beanA,那么beanA, beanB共用一个beanA的实例.
<beans>
  <bean name="beanA">
  </bean>

  <bean name="beanB">
    <property name="beana" ref="beanA"/>
  </bean>

  <bean name="beanC">
    <property name="beana" ref="beanA"/>
  </bean>
</beans>

这在多线程中会出现问题:
比如在线程1中:  
beanB = (BeanB)ApplicationContext.getBean("beanB");
beanB.getBeanA().setName("beanA in thread1");

在线程2中:  
beanC = (BeanC)ApplicationContext.getBean("beanC");
beanB.getBeanA().setName("beanA in thread2");

因为BeanA是单例模式, 只有一个实例, 也就是说线程1和线程2共用了一个BeanA的实例.  这不需要同步吗?
------解决思路----------------------
单例模式肯定有同步问题……比如我有一个Bean:
public class A {
private int i;

public void test() {
i++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
i--;
System.out.println(i);
}
}

然后测试代码:
public class RunnableTest {
public static void main(String[] args) {
final ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
for (int i = 0; i < 10; i++)
new Thread(new Runnable() {

@Override
public void run() {
A a = context.getBean(A.class);
for (int i = 0; i < 10; i++)
a.test();
}

}).start();
}
}

每次输出结果都不同,反正不等于0;给bean加上scope="prototype"之后输出正常,给test()方法加上synchronized之后输出也正常。这显然是出现同步问题了
------解决思路----------------------
SPRING默认是单例模式,你可以改成原型模式啊
  相关解决方案