JAVA網絡面試,這一篇就夠了

單例模式

一、使用單例模式的原因和方法

  1. 原因:多個線程要操作同一對象,要保證對象的唯一性
  2. 方法:實例化過程中只實例化一次

二、單例模式三個主要特點:

  1. 構造方法私有化;
  2. 實例化的變量引用私有化;[ 有一個實例化的過程(只有一次),產生實例化對象 new ]
  3. 獲取實例的方法共有。[ 提供返回實例對象的方法 getInstace() ]

三、評判單例模式的標準

  1. 線程的安全性、
  2. 性能、
  3. 懶加載(lazy )

四、 常用的單例模式

1、 單例的餓漢模式

<code>
public class Singleton {
/*
* 利用靜態變量來記錄Singleton的唯一實例

* 直接初始化靜態變量,這樣就可以確保線程安全了
*/
private static Singleton uniqueInstance = new Singleton();

/*
* 構造器私有化,只有Singleton類內才可以調用構造器
*/
private Singleton() {

}

public static Singleton getInstance() {
return uniqueInstance;
}

}/<code>
  • 線程安全性:在加載的時候已經被實例化,所以只有這一次,線程安全的。JVM ClassLoader
  • 懶加載:沒有延遲加載,好長時間不使用,影響性能
  • 性能比較好

2、 懶漢式

<code>public class HoonSingleton {
private static HoonSingleton instance=null;
private HoonSingleton(){
}
public static HoonSingleton getInstance(){
if(null==instance)
instance=new HoonSingleton();
return instance;
}
}/<code>
  • 線程安全性:不能保證實例對象的唯一性(不安全)
  • 懶加載:延遲加載

3、懶漢的雙重加鎖機制 (DCL :Double-Check-Locking)

<code>package cn.njauit;

public class Singleton {
/*
* 利用靜態變量來記錄Singleton的唯一實例
* volatile 關鍵字確保:當uniqueInstance變量被初始化成Singleton實例時,
* 多個線程正確地處理uniqueInstance變量(保證了有序性,解決了編譯重排重排和運行重排問題)
*
*/
private volatile static Singleton uniqueInstance;

/*
* 構造器私有化,只有Singleton類內才可以調用構造器
*/
private Singleton() {

}

/*
*
* 檢查實例,如果不存在,就進入同步區域
*/
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) { //進入同步區域
if (uniqueInstance == null) { //在檢查一次,如果為null,則創建
uniqueInstance = new Singleton();
}
}
}


return uniqueInstance;
}

}/<code>
  • 性能比較好
  • 懶加載:是
  • 線程的安全性:安全

4、靜態內部類(Holder 型)

靜態內部類延遲加載

<code>package cn.njauit;

public class Singleton {

//聲明類的時候,成員變量中不聲明實例變量,而放到內部靜態類中
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
//懶加載
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}/<code>

5.1、枚舉單例示例

<code>public enum  EnumSingleton {
INSTANCE;//INSTANCE 就是 EnumSingleton 的常量,只能初始化一次,天生為單例
public EnumSingleton getInstance(){
return INSTANCE;
}
}/<code>

5.2、 完整的枚舉單例

<code>package cn.njauit;

public class EnumSingletonDemo {
private EnumSingletonDemo() {
}

//匿名內部靜態枚舉類具有延遲加載性質
private enum EnumHolder {
/**
* 創建一個枚舉對象,該對象天生為單例
*/
INSTANCE;
private EnumSingletonDemo instance;

EnumHolder() {
instance = new EnumSingletonDemo();
}
}
//懶加載 //對外暴露一個獲取Instance的靜態方法
public static EnumSingletonDemo getInstance() {
return EnumHolder.INSTANCE.instance;
}

}
/<code>

本文由 Java快速開發學習 發佈


分享到:


相關文章: