j 2 ee高同時実行時のグローバル変数の使用に注意すべき問題

1671 ワード

開発では,グローバル変数の使用が頻繁であるが,マルチスレッドへのアクセスには,グローバル変数の使用に注意すべき点が多く,以下に大まかなまとめを行った.
グローバル変数を使用する場合:
1:読み取り専用のグローバル変数を定義する場合は、修正されないようにfinal修飾を加えなければなりません.私有であってもfinalを加えて反射修正を防止しなければならない.
2:複数回読み書きが必要なグローバル変数については、必ずThreadLocalでカプセル化し、マルチスレッド同時時に変数が複数回付与されるなどの安全でない現象を避けなければならない.
ThreadLocalパッケージの静的グローバル変数とプライベートグローバル変数のコード例:
import java.util.ArrayList;
import java.util.List;

public class RollDice {

	//ThreadLocal      
	public static ThreadLocal> threadRollList = new ThreadLocal>(){
		//        ThreadRollList       ,  ThreadLocal     。
		@Override
		protected synchronized List initialValue() {
			return new ArrayList(0);
		}
	};
	//           ,        ,   bug.
	public static List rollList = new ArrayList(0);
	
	
	//      
	public ThreadLocal> priTreadRollList = new ThreadLocal>(){

		//       ,ThreadLocal        ,        ,      synchronized。
		@Override
		protected List initialValue() {
			return new ArrayList(0);
		}
		
	};
	
	//    
	public static void main(String[] args) {
		//ThreadLocal    
		threadRollList.get().add(new Object());
		//        
		rollList.add(new Object());
	}
	
}

ここでは、同時性の問題を解決するための2つの一般的なシナリオを拡張し、比較します.
synchronizedを使用して修飾します.この方法は単一スレッドキューの実行に相当し、待機が必要で、パフォーマンスが損なわれ、メモリの追加オーバーヘッドが増加しないという利点があります.
ThreadLocalを使用して変数をカプセル化することは、実行スレッドに変数を投げ込むことに相当し、newごとに新しいスレッドが作成され、変数もnewされる(必ずしも毎回newとは限らないが、これはプログラムの書き方次第だ).パフォーマンスに影響はありませんが、システムの追加のメモリオーバーヘッドが増加しますが、実行が完了すると破棄されるメカニズムにより、ThreadLocalは比較的最適化された同時ソリューションになります.