java單態

java單態,計算機語言,該模式主要保證在Java應用程式中Class只有一個實例存在,可以節省記憶體,有利於Java垃圾回收。

基本介紹

  • 中文名:java單態
  • 外文名:Java singleton
  • 保證:保證在Java應用程式中
  • 實例:Class只有一個實例存在
  • 好處:還在於可以節省記憶體
  • 回收:有利於Java垃圾回收
單態定義,注意事項,單態模式的演化,一,單態模式1,二,單態模式2,三,單態模式3,四,單態模式4,,

單態定義

Singleton模式就為我們提供了這樣實現的可能。使用Singleton的好處還在於可以節省記憶體,因為它限制了實例的個數,有利於Java垃圾回收(garbage collection)。

注意事項

有時在某些情況下,使用Singleton並不能達到Singleton的目的,如有多個Singleton對象同時被不同的類裝入器裝載;在EJB這樣的分散式系統中使用也要注意這種情況,因為EJB是跨伺服器,跨JVM的

單態模式的演化

單態模式是個簡單的模式,但是這個簡單的模式也有很多複雜的東西。

一,單態模式1

import java.util.*;
class Singleton
{
private static Singleton instance;
private Vector v;
private boolean inUse;
private Singleton()
{
v = new Vector();
v.addElement(new Object());
inUse = true;
}
public static Singleton getInstance()
{
if (instance == null) //1
instance = new Singleton(); //2
return instance; //3
}
}
這個單態模式是不安全的,為什麼說呢 ?因為沒考慮多執行緒,如下情況
Thread 1 調用getInstance() 方法,並且判斷instance是null,然後進入if模組,
在實例化instance之前,
Thread 2搶占了Thread 1的cpu
Thread 2 調用getInstance() 方法,並且判斷instance是null,然後進入if模組,
Thread 2 實例化instance 完成,返回
Thread 1 再次實例化instance
這個單態已經不在是單態

二,單態模式2

public static synchronized Singleton getInstance()
{
if (instance == null) //1
instance = new Singleton(); //2
return instance; //3
}
採用同步來解決,這種方式解決了問題,但是仔細分析正常的情況下只有第一次時候,進入對象的實例化,須要同步,其它時候都是直接返回已經實例化好的instance不須要同步,大家都知到在一個多執行緒的程式中,如果同步的消耗是很大的,很容易造成瓶頸

三,單態模式3

public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
同步改成塊同步,而不使用函式同步,但是仔細分析,
又回到了模式一的狀態,再多執行緒的時候根本沒有解決問題

四,單態模式4,

也就是很多人採用的Double-checked locking
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) { //1
if (instance == null) //2
instance = new Singleton(); //3
}
}
return instance;
}
這樣,模式一中提到的問題解決了。不會出現多次實例化的現象
當第一次進入的時候,保正實例化時候的單態,在實例化後,多執行緒訪問的時候直接返回,不須要進入同步模組,既實現了單態,又沒有損失性能。表面上看我們的問題解決了,但是再仔細分析:
我們來假象這中情況:
Thread 1 :進入到//3位置,執行new Singleton(),但是在構造函式剛剛開始的時候被Thread2搶占cpu
Thread 2 :進入getInstance(),判斷instance不等於null,返回instance,
(instance已經被new,已經分配了記憶體空間,但是沒有初始化數據)
Thread 2 :利用返回的instance做某些操做,失敗或者異常
Thread 1 :取得cpu初始化完成
過程中可能有多個執行緒取到了沒有完成的實例,並用這個實例作出某些操做。
出現以上的問題是因為
mem = allocate(); //分配記憶體
instance = mem; //標記instance非空
//未執行構造函式,thread 2從這裡進入
ctorSingleton(instance); //執行構造函式
//返回instance

相關詞條

熱門詞條

聯絡我們