在Spring框架下如何保證線程安全,如何很happy順暢地並發編程。
常見的如下面的這坨代碼,在Spring中,默認是單例的,也就是說,在同一時刻只有一個SpringOrdinaryClass的單實例。這時候如果類中有一個可變的成員變量,如VariableClass類型的var。在多
public class SpringOrdinaryClass { private VariableClass var = new VaribaleClass(); public void run(){ } //getter & setter } class VariableClass{ private int i; private String s; //getter & setter }
線程同時訪問的時候,顯然是線程不安全的,每個線程都有修改var值得可能。
So,在Spring中我們應該怎么做?
我總結是兩種情況:
一種是如果var的值需要被多線程共享,即線程A的修改希望被線程B知道,那么應該使用同步;
另一種是var的值不需要被共享,每個線程都想要單獨保留一份自己的修改,並且各自的修改不會受到其他線程的影響,這時候應該使用ThreadLocal。
同步無非就是各種加鎖,如果可變變量是集合等,還可以使用同步容器包裝,或使用線程安全的容器替代,確保實例是被安全發布。在接下來的使用中,同樣需要使用同步機制,確保線程安全。ThreadLocal方式,是典型的用空間換時間。客戶端向服務器發起一次請求,有這么一個特點,即一個線程唯一對應一次http請求,只要確保線程不變,那么可以確保始終對應唯一的一個請求id。借助這條特性,開發者可以將一次請求的所有信息都綁定到當前線程上。不難想象ThreadLocal的內部實現,鍵就是當前線程,值為任何你想綁定到線程上的信息。通過get和set方法,開發者可以安全的訪問和保存當前請求指定信息,做到線程安全。上面的代碼可以改為private ThreadLocal<VariableClass> varThreadLocal = new ThreadLocal<VariableClass>。
上面只是簡要介紹思路,更多詳細內容,可查閱相關資料。