j2ee高併發時使用全局變量須要注意的問題

原文: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變成比較優化的併發解決方案。線程

相關文章
相關標籤/搜索