Spring 不保证 bean 的线程平安。
默许 spring 容器中的 bean 是单例的。当单例中存在竞态前提,即有线程平安问题。以下面的例子
计数类
package constxiong.interview.threadsafe; /** * 计数类 * @author ConstXiong * @date 2019-07-16 14:35:40 */ public class Counter { private int count = 0; public void addAndPrint() { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(++count); } }
spring 配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="counter" class="constxiong.interview.threadsafe.Counter" /> </beans>
测试类
package constxiong.interview.threadsafe; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class CounterTest { public static void main(String[] args) { final ApplicationContext context = new ClassPathXmlApplicationContext("spring_safe.xml"); for (int i = 0; i < 10; i++) { new Thread(){ @Override public void run() { Counter counter = (Counter)context.getBean("counter"); for (int j = 0; j < 1000; j++) { counter.addAndPrint(); } } }.start(); } } }
打印效果开首和末端
1 5 7 4 2 6 3 8 9 . . . 9818 9819 9820 9821 9822 9823 9824 9825
希冀打印出的最大值应该是 10000
修正 spring 配置文件,把 bean 的作用域改成 prototype
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="counter" class="constxiong.interview.threadsafe.Counter" scope="prototype"/> </beans>
测试效果输出10个 1000
即每一个线程都建立了一个 Counter 对象,线程内单独计数,不存在线程平安问题。然则不是我们想要的效果,打印出 10000。
所以 spring 治理的 bean 的线程平安跟 bean 的建立作用域和 bean 地点的运用环境是不是存在竞态前提有关,spring 并不能保证 bean 的线程平安。
以上就是spring中的bean是线程平安的吗?的细致内容,更多请关注ki4网别的相干文章!