二重検査単例モードの詳細説明
1489 ワード
/** 単例モード-二重チェックロック @author zz
*/public class SingleTon3 {
}注意事項:問題:if(singleTon=null)を2回判断する必要があるのはなぜですか?
解析:最初のチェック:インスタンスを1回作成する必要がある単一インスタンスモードのため、getInstanceメソッドを後で再度呼び出すと、以前に作成したインスタンスが直接返されるため、同期メソッドのコードを実行する必要がなくなり、パフォーマンスが大幅に向上します.1回目のチェックを入れなければ、上の怠け者モードと変わらず、毎回競合ロックに行きます.
2回目の検査:2回目の検査がなければ、スレッドt 1が1回目の検査を実行したと仮定してnullと判断し、このときt 2もCPU実行権を取得し、1回目の検査も実行し、nullと判断する.次にt 2はロックを取得し、インスタンスを作成する.このときt 1はまたCPU実行権を獲得し、前回第1回目のチェックを行ったためnull(再判断しない)となり、ロックを取得した後、直接インスタンスを作成する.結果として、複数のインスタンスが作成されます.したがって、同期コードで2回目のチェックを行い、インスタンスが空の場合は作成する必要があります.質問:なぜvolatileを追加するのですか?
新wオブジェクトは実際には4つのステップである:a.classオブジェクトがロードされているかどうかを見て、そうでなければclassオブジェクトを先にロードし、b.メモリ空間を割り当て、インスタンスを初期化する.c.コンストラクション関数を呼び出す.d.参照にアドレスを返します.volatileを入れないと何か問題が発生しますか?
1.2つのスレッドA,B,Bは文4に実行され、Aは文1 2に実行された.2.Bは命令が並べ替えられたため、c,dが逆転され、ちょうどdが実行され、cがまだ実行されていない間にBが掛けられた.3.このときAは文1に実行され、singletonがnullに等しくないことを発見し、まだ構築が完了していないsingletonオブジェクトを上位呼び出しに返した.
*/public class SingleTon3 {
private SingleTon3(){}; //
private static volatile SingleTon3 singleTon=null;
public static SingleTon3 getInstance(){
//
if(singleTon==null){ // 1
synchronized(SingleTon3.class){ // 2
//
if(singleTon==null){ // 3
singleTon=new SingleTon3(); // 4
}
}
}
return singleTon;
}注意事項:問題:if(singleTon=null)を2回判断する必要があるのはなぜですか?
解析:最初のチェック:インスタンスを1回作成する必要がある単一インスタンスモードのため、getInstanceメソッドを後で再度呼び出すと、以前に作成したインスタンスが直接返されるため、同期メソッドのコードを実行する必要がなくなり、パフォーマンスが大幅に向上します.1回目のチェックを入れなければ、上の怠け者モードと変わらず、毎回競合ロックに行きます.
2回目の検査:2回目の検査がなければ、スレッドt 1が1回目の検査を実行したと仮定してnullと判断し、このときt 2もCPU実行権を取得し、1回目の検査も実行し、nullと判断する.次にt 2はロックを取得し、インスタンスを作成する.このときt 1はまたCPU実行権を獲得し、前回第1回目のチェックを行ったためnull(再判断しない)となり、ロックを取得した後、直接インスタンスを作成する.結果として、複数のインスタンスが作成されます.したがって、同期コードで2回目のチェックを行い、インスタンスが空の場合は作成する必要があります.質問:なぜvolatileを追加するのですか?
新wオブジェクトは実際には4つのステップである:a.classオブジェクトがロードされているかどうかを見て、そうでなければclassオブジェクトを先にロードし、b.メモリ空間を割り当て、インスタンスを初期化する.c.コンストラクション関数を呼び出す.d.参照にアドレスを返します.volatileを入れないと何か問題が発生しますか?
1.2つのスレッドA,B,Bは文4に実行され、Aは文1 2に実行された.2.Bは命令が並べ替えられたため、c,dが逆転され、ちょうどdが実行され、cがまだ実行されていない間にBが掛けられた.3.このときAは文1に実行され、singletonがnullに等しくないことを発見し、まだ構築が完了していないsingletonオブジェクトを上位呼び出しに返した.