Javaコンカレント:スレッドセキュリティの単一モード
転載は出典を明記してください:jiq・欽'stechnical Blog
1、餓漢式
欠点:クラスがロードされるとスペースが割り当てられ、使用しないとメモリ領域が消費されます.
2、怠け者
2.1通常ロックモード
欠点:各スレッド呼び出しgetInstanceはロックされ、効率が低く、getInstanceが初めて呼び出されたときにのみロックされたい場合は、次の二重検出スキームを参照してください.
2.2プレースホルダモード(推奨)
Javaメカニズムでは、内部クラスSingletonHolderはgetInstance()メソッドが最初に呼び出されたときにのみロードされ(lazyが実現される)、そのロードプロセスはスレッドが安全であることが規定されているため、怠け者式の単一例に属する.内部クラスがロードされるとinstanceがインスタンス化されます.
2.3二重検査
通常の二重検査:
欠点:命令の並べ替え問題、私のこの文章を参考にします
.
ソリューション:
instanceインスタンス変数に対してvolatileで修飾すればよいが,volatileで修飾すればinstance=new Singleton()を確保できる.対応する命令は並べ替えられません.
1、餓漢式
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return INSTANCE;
}
}
欠点:クラスがロードされるとスペースが割り当てられ、使用しないとメモリ領域が消費されます.
2、怠け者
2.1通常ロックモード
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
欠点:各スレッド呼び出しgetInstanceはロックされ、効率が低く、getInstanceが初めて呼び出されたときにのみロックされたい場合は、次の二重検出スキームを参照してください.
2.2プレースホルダモード(推奨)
Javaメカニズムでは、内部クラスSingletonHolderはgetInstance()メソッドが最初に呼び出されたときにのみロードされ(lazyが実現される)、そのロードプロセスはスレッドが安全であることが規定されているため、怠け者式の単一例に属する.内部クラスがロードされるとinstanceがインスタンス化されます.
public class Singleton {
private Singleton() { }
privatestatic class SingletonHolder {
// , , SingletonHolder
// :static , JVM
static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
2.3二重検査
通常の二重検査:
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
欠点:命令の並べ替え問題、私のこの文章を参考にします
.
ソリューション:
instanceインスタンス変数に対してvolatileで修飾すればよいが,volatileで修飾すればinstance=new Singleton()を確保できる.対応する命令は並べ替えられません.
public class Singleton {
private static volatile Singletoninstance = null; // volatile
private Singleton() { } // ,
public static Singleton getInstance() {
if(instance == null) { //
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}