所謂類的單例模式設計,就是採取一定的方法保證在整個系統中,對某個類只能存在一個物件範例,並且該類只提供一個取得其物件範例的方法(靜態)
步驟如下:
public class SingletonTest01 {
public static void main(String[] args) {
Singleton st=Singleton.getInstance();//類裝載時便進行範例化
Singleton st2=Singleton.getInstance();
System.out.println(st==st2);
System.out.println(st.hashCode());
System.out.println(st2.hashCode());
}
}
class Singleton{
//餓漢式
//1.構造器私有化
private Singleton()
{
}
//2.本類內部建立物件範例
private final static Singleton instance =new Singleton();
//3。提供一個公有靜態方法
public static Singleton getInstance()
{
return instance;
}
}
優點:執行緒安全(實現同步)
缺點:傳引數困難,且容易造成記憶體浪費(裝載即範例,但是有可能用不到)
步驟如下:
public class SingletonTest03 {
public static void main(String[] args) {
System.out.println("執行緒不安全!!!!");
Singleton st=Singleton.getInstance();//類裝載時便進行範例化
Singleton st2=Singleton.getInstance();
System.out.println(st==st2);
System.out.println(st.hashCode());
System.out.println(st2.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton()
{
}
public static Singleton getInstance()
{
if(instance==null)
instance=new Singleton();
return instance;
}
}
優點:延遲載入
缺點:執行緒不安全(多執行緒下,若一個執行緒進入了if(singleton==null)判斷語句塊,還未來得及往下執行,另一個執行緒也通過了這個判斷語句,這時便會產生多個範例)
synchronized同步方法,每一次只允許一個執行緒存取。
public class SingletonTest04 {
public static void main(String[] args) {
Singleton st=Singleton.getInstance();
Singleton st2=Singleton.getInstance();
System.out.println(st==st2);
System.out.println(st.hashCode());
System.out.println(st2.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton()
{
}
public static synchronized Singleton getInstance()
{
//此方法效率低下
if(instance==null)
instance=new Singleton();
return instance;
}
}
優點:解決了執行緒不安全的問題
缺點:效率太低(每個執行緒在想獲得類的範例的時候,執行getInstance()方法都要進行同步。其實只執行一次程式碼範例化就足夠了。)
class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static Singleton getInstance()
{
if(instance==null)
{
synchronized(Singleton.class)
{
instance=new Singleton();
}
}
return instance;
}
}
寫法錯誤,同步並不能起到真正的作用,實際開發不可用。
class Singleton{
private static volatile Singleton instance;
private Singleton()
{
}
public static synchronized Singleton getInstance()
{
if(instance==null)//解決了效率低下
{
synchronized(Singleton.class)
{
if(instance==null)//雙重檢查,實現一次範例化
{
instance=new Singleton();
}
}
}
return instance;
}
}
實現了延時載入,與執行緒安全,同時保證了效率。
class Singleton
{
private static volatile Singleton instance;
private Singleton()
{
}
//外類裝載不會馬上裝載的
private static class SingletonInstance{
private static final Singleton Instance=new Singleton();//餓漢式
}
//用到他的時候才裝載(JVM裝載時執行緒安全)
public static synchronized Singleton getInstance()
{
return SingletonInstance.Instance;//懶漢式
}
}
優點:
public class SingletonTest08 {
public static void main(String[] args) {
Singleton st=Singleton.Instance;
Singleton st2=Singleton.Instance;
System.out.println(st==st2);
System.out.println(st.hashCode());
System.out.println(st2.hashCode());
}
}
enum Singleton{//列舉實現單利
Instance;//屬性
public void sayOK()
{
System.out.println("ok~");
}
}
優點:
列舉方式實現單例,不僅能夠避免多執行緒同步問題,而且還能防止反序列化重新建立新的物件。