方式7種
- 餓漢式(靜態變量)
- 優勢:
- 簡單易寫
- 線程安全
- 劣勢:浪費內存空間,只要類進行了加載,即使不使用對應的實例,也會進行加載
class MySingleton {
private static MySingleton singleton = new MySingleton();
private MySingleton() {
}
public static MySingleton getInstance() {
return singleton;
}
}
- 餓漢式(靜態代碼塊)
- 優勢:與靜態變量差不錯的意思
- 劣勢:缺點也和靜態變量差不多
class StaticBlockSingleton {
private static StaticBlockSingleton singleton;
static {
singleton = new StaticBlockSingleton();
}
private StaticBlockSingleton() {
}
public static StaticBlockSingleton getInstance() {
return singleton;
}
}
- 懶漢式(非線程安全)
- 優勢:在不需要使用實例的時候不會進行創建,不會浪費內存空間
- 劣勢:在多線程的情況下,可能產生不同的對象
- 總結:不推薦使用
class ThreadUnSafeSingleton {
private static ThreadUnSafeSingleton singleton3;
private ThreadUnSafeSingleton() {
}
public static ThreadUnSafeSingleton getInstance() {
if (singleton3 == null) {
singleton3 = new ThreadUnSafeSingleton();
}
return singleton3;
}
}
- 懶漢式(線程安全,效率低)
- 優勢:在多線程使用的情況下,線程安全了
- 劣勢:由於將鎖關鍵字synchronized放在方法上,鎖定範圍較大,效率不高
- 總結:不建議使用
class ThreadSafeSingleton {
private static ThreadSafeSingleton singleton;
private ThreadSafeSingleton() {
}
public static synchronized ThreadSafeSingleton getInstance() {
if (singleton == null) {
singleton = new ThreadSafeSingleton();
}
return singleton;
}
}
- 雙檢查(線程安全)
- 優勢:其實也是懶漢式的一種,線程安全,且縮小了鎖的鎖定範圍,效率比懶漢式高一點(可忽略不及)
- 劣勢:不曉得
- 總結:可以使用
class DoubleCheckSingleton {
private static DoubleCheckSingleton singleton5;
private DoubleCheckSingleton() {
}
public static DoubleCheckSingleton getInstance() {
if (singleton5 == null) {
synchronized (DoubleCheckSingleton.class) {
if (singleton5 == null) {
singleton5 = new DoubleCheckSingleton();
}
}
}
return singleton5;
}
}
- 靜態內部類
- 優勢:屬於懶加載一種,外部類加載時不會加載內部類,所以在獲取實例錢不會創建對象,節約了內存
- 劣勢:不曉得
- 總結:推薦使用
class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {
}
public static StaticInnerClassSingleton getInstance() {
return InnerClass.singleton;
}
private static class InnerClass {
private static StaticInnerClassSingleton singleton = new StaticInnerClassSingleton();
}
}
- 枚舉
- 優勢:
- 高級,洋氣,曉得的人相對比較小
- 線程安全
- 防止反序列化重新創建新的對象
- 劣勢:不曉得
enum EnumSingleton {
INSTANCE;
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}