首頁  >  文章  >  Java  >  spring中的bean是線程安全的嗎?

spring中的bean是線程安全的嗎?

(*-*)浩
(*-*)浩轉載
2019-09-12 16:14:593103瀏覽

spring 中的 bean 是線程安全的嗎?

spring中的bean是線程安全的嗎?

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

spring中的bean是線程安全的嗎?即每個執行緒都建立了一個Counter 對象,執行緒內獨自計數,不存在執行緒安全性問題。但不是我們想要的結果,印出 10000。

所以 spring 管理的 bean 的線程安全跟 bean 的創建作用域和 bean 所在的使用環境是否存在競態條件有關,spring 並不能保證 bean 的線程安全。

以上是spring中的bean是線程安全的嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除