原文:https://blog.csdn.net/jston_learn/article/details/21617311java
開發中,全局變量的使用很頻繁,但對於多線程的訪問,使用全局變量須要注意的地方有不少,下面作了個大概的總結。安全
全局變量的使用場合:多線程
1:定義只讀的全局變量時,必須加final修飾,防止被修改。哪怕是私有的,也得加final,防止被反射修改。併發
2:對於須要屢次讀寫的全局變量,必定要用ThreadLocal封裝,避免多線程併發時變量被屢次賦值等不安全的一些現象。ide
ThreadLocal封裝靜態全局變量和私有全局變量的代碼示例:性能
import java.util.ArrayList; import java.util.List; public class RollDice { //ThreadLocal封裝靜態變量 public static ThreadLocal<List<Object>> threadRollList = new ThreadLocal<List<Object>>(){ //這裏加同步是由於ThreadRollList是靜態全局變量,防止ThreadLocal自己被併發。 @Override protected synchronized List<Object> initialValue() { return new ArrayList<Object>(0); } }; //用此種方式定義全局變量,遭遇多線程併發時,會出現bug. public static List<Object> rollList = new ArrayList<Object>(0); //私有全局變量 public ThreadLocal<List<Object>> priTreadRollList = new ThreadLocal<List<Object>>(){ //由於是私有變量,ThreadLocal自己會被放進線程,因此不用擔憂併發,所以也不須要synchronized。 @Override protected List<Object> initialValue() { return new ArrayList<Object>(0); } }; //調用方式 public static void main(String[] args) { //ThreadLocal調用方式 threadRollList.get().add(new Object()); //普通定義調用方式 rollList.add(new Object()); } }
這裏再擴展一下解決併發問題的兩種經常使用的方案並進行對比:優化
使用synchronized來修飾,此方法至關於單線程隊列執行,須要等待,有損性能,好處是不會增長內存的額外開銷。.net
使用ThreadLocal封裝變量,至關於把變量丟進執行線程中去,每new一個新的線程,變量也會new一次(不必定每次都new,這個要看程序怎麼寫。),對性能沒有影響,但會增長系統額外的內存開銷,但其執行完畢就銷燬的機制使得ThreadLocal變成比較優化的併發解決方案。線程