1.餓漢模式(線程安全,調用效率高,但是不能延時加載):
package com.yanwu.www.demo;
/*
* 測試單例模式
*
* 餓漢模式
*
* @author harvey
*
*/
public class SingletonDemo1 {
//類初始化時立即加載對象(沒有延遲加載的優勢),天然的線程安全
private static SingletonDemo1 instance=new SingletonDemo1();
//構造器私有化
private SingletonDemo1(){}
//方法沒有同步,調用效率高
public static SingletonDemo1 getInstance(){
return instance;
}
}
2.懶漢模式(線程安全,調用效率不高,但是能延時加載):
package com.yanwu.www.demo;
/*
*測試單例模式
*
*懶漢模式
*
*@author harvey
*
*/
public class SingletonDemo2 {
//類初始化時,不初始化這個對象(延時加載,真正用的時候再創建)
private static SingletonDemo2 instance;
//構造器私有化
private SingletonDemo2(){}
//方法同步,調用效率低
public static synchronized SingletonDemo2 getInstance(){
if(instance==null){
instance=new SingletonDemo2();
}
return instance;
}
}
3.雙重檢測鎖模式(由於JVM底層模型原因,偶爾會出問題,不建議使用):
package com.yanwu.www.demo;
/*
* 單例模式
*
* 雙重檢測鎖式
*
* 由於JVM底層內部模型原型,偶爾會出現問題,不建議使用
*
* @author harvey
*/
public class SingletonDemo5 {
private volatile static SingletonDemo5 SingletonDemo5;
private SingletonDemo5() {
}
public static SingletonDemo5 newInstance() {
if (SingletonDemo5 == null) {
synchronized (SingletonDemo5.class) {
if (SingletonDemo5 == null) {
SingletonDemo5 = new SingletonDemo5();
}
}
}
return SingletonDemo5;
}
}
4.靜態內部類式(線程安全,調用效率高,可以延時加載):
package com.yanwu.www.demo;
/*
* 單例模式
*
* 靜態內部類的實現
*
* 1.外部類沒有static 屬性,不會像餓漢一樣立即加載對象
*
* 2.只有真正調用getInstance()才會加載靜態內部類,加載時是線程安全的
*
* 3.兼並延時調用和並發高效調用
*
* @author harvey
*
*/
public class SingletonDemo3 {
private static class SingletonClassInstance{
private static final SingletonDemo3 instance=new SingletonDemo3();
}
private SingletonDemo3(){}
public static SingletonDemo3 getInstance(){
return SingletonClassInstance.instance;
}
}
5.枚舉類(線程安全,調用效率高,不能延時加載,可以天然的防止反射和反序列化調用):
package com.yanwu.www.demo;
/*
* 單例模式
*
* 枚舉式實現
*
* 1.避免了反射和反序列化的漏洞
*
* 2.沒有延時加載的效果
*
* @author harvey
*/
public enum SingletonDemo4 {
//枚舉元素本身就是單例
INSTANCE;
//添加自己需要的操作
public void singletonOperation(){
}
}
如何選用:
-單例對象 占用資源少,不需要延時加載,枚舉 好於 餓漢
-單例對象 占用資源多,需要延時加載,靜態內部類 好於 懶漢式
