單例模式
一個類只有一個實例,並且可以全局訪問使用
應用場景
如賬戶管理類,數據庫操作類等(某個對象頻繁被訪問使用)
常用方式
- 餓漢式
- 懶漢式
- 同步加鎖
- DCL雙重加鎖驗證
- 靜態內部類
- 枚舉單例
餓漢式
加載類的同時立即進行初始化操作,對資源消耗很大
public class SingleTest {
public static final SingleTest singleTest1=new SingleTest();
public SingleTest() {
}
public static SingleTest getSingleTest1(){
return singleTest1;
}
}
懶漢式
優點:需要使用時候才進行初始化加載
缺點:線程不安全,在多線程中很容易出現不同步的情況
public class SingleTest1 {
private static SingleTest1 instance=null;
public SingleTest1() {
}
public static SingleTest1 getInstance(){
if(instance==null){
instance=new SingleTest1();
}
return instance;
}
}
同步加鎖
優點:解決線程安全問題
缺點:每次實例需要判斷加鎖狀態,效率低下
public class SingleTest2 {
private static SingleTest2 instance=null;
public SingleTest2() {
}
public static synchronized SingleTest2 getInstance(){
if(instance==null){
instance=new SingleTest2();
}
return instance;
}
}
DCL雙重校驗
優點:併發不高的情況下可以完美運行(推薦使用,客戶端幾乎不存在高併發情況)
缺點:JDK1.5以前可能會出現instance爲初始化的問題(現在的Android幾乎都是1.7 1.8了幾乎可以略率此問題)
public class SingleTest4 {
private static SingleTest4 instance=null;//靜態變量
public SingleTest4() {
}
public static SingleTest4 getInstance(){
if (instance == null) {//第一層校驗
synchronized (SingleTest4.class) {
if (instance == null) {//第二層校驗
instance = new SingleTest4();
}
}
}
return instance;
}
}
靜態內部類
優點:延遲加載,線程安全,內存消耗少(推薦使用)
public class SingleTest5 {
private SingleTest5() {
}
public static final SingleTest5 getInstance() {
return SingletonHolder.INSTANCE;
}
//定義的靜態內部類
private static class SingletonHolder {
private static final SingleTest5 INSTANCE = new SingleTest5(); //創建實例的地方
}
}
枚舉單例
優點:線程安全,防反序列化,防反射,寫法簡單
public enum SingleTest6 {
//第一種方式
// INSTANCE;
// private CaiPiao instance;
//
// SingleTest6() {
// instance = new CaiPiao();
// }
//
// public CaiPiao getInstance() {
// return instance;
// }
//
// class CaiPiao {
//
// }
//第二種方式
INSTANCE2{
@Override
protected void CaiPiao() {
System.out.println("彩票");
}
};
protected abstract void CaiPiao();
}