單態定義:
Singleton模式主要作用是保證在Java應用程序中
Singleton模式就為我們提供了這樣實現的可能
使用Singleton注意事項
有時在某些情況下
單態模式的演化
單態模式是個簡單的模式
(注意
一
import java
class Singleton
{
private static Singleton instance;
private Vector v;
private boolean inUse;
private Singleton()
{
v = new Vector();
v
inUse = true;
}
public static Singleton getInstance()
{
if (instance == null) //
instance = new Singleton(); //
return instance; //
}
}
這個單態模式是不安全的
Thread
在實例化instance之前
Thread
Thread
Thread
Thread
這個單態已經不在是單態
二
public static synchronized Singleton getInstance()
{
if (instance == null) //
instance = new Singleton(); //
return instance; //
}
采用同步來解決
三
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton
instance = new Singleton();
}
}
return instance;
}
同步改成塊同步
又回到了模式一的狀態
四
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton
if (instance == null) //
instance = new Singleton(); //
}
}
return instance;
}
這樣
當第一次進入的時候
我們來假象這中情況
Thread
Thread
(instance已經被new
Thread
Thread
過程中可能有多個線程取到了沒有完成的實例
-----------------------------------------
出現以上的問題是因為
mem = allocate(); //分配內存
instance = mem; //標記instance非空
//未執行構造函數
ctorSingleton(instance); //執行構造函數
//返回instance
------------------------------------------
五
字節碼的使用方法見這裡
class Singleton
{
private static Singleton instance;
private boolean inUse;
private int val;
private Singleton()
{
inUse = true;
val =
}
public static Singleton getInstance()
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
得到的字節碼
;asm code generated for getInstance
;instance ref
;non
;has not run
上邊的字節碼證明
六
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton
Singleton inst = instance; //
if (inst == null)
{
synchronized(Singleton
inst = new Singleton(); //
}
instance = inst; //
}
}
}
return instance;
}
利用Double
(下邊這段話我只能簡單的理解
The code in Listing
The Java Language Specification (JLS) demands that code within a synchronized block
not be moved out of a synchronized block
code not in a synchronized block cannot be moved into a synchronized block
A JIT compiler would see an optimization opportunity here
This optimization would remove the code at
//
list
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton
Singleton inst = instance; //
if (inst == null)
{
synchronized(Singleton
//inst = new Singleton(); //
instance = new Singleton();
}
//instance = inst; //
}
}
}
return instance;
}
If this optimization takes place
如果這個優化發生
以下部分為了避免我翻譯錯誤誤導打家
Another idea is to use the keyword volatile for the variables inst and instance
According to the JLS (see Resources)
be sequentially consistent
But two problems occur with trying to use volatile to fix the problem with
double
The problem here is not with sequential consistency
Code is being moved
Many JVMs do not implement volatile correctly regarding sequential consistency anyway
The second point is worth expanding upon
Listing
class test
{
private volatile boolean stop = false;
private volatile int num =
public void foo()
{
num =
stop = true; //This can happen first
//
}
public void bar()
{
if (stop)
num += num; //num can ==
}
//
}
According to the JLS
they should be sequentially consistent
num must have been set to
However
you cannot count on this behavior
Therefore
thread
This could lead thread
There are additional problems with volatile and the atomicity of
but this is beyond the scope of this article
See Resources for more information on this topic
簡單的理解上邊這段話
最終的解決方案
(
(
class Singleton
{
private Vector v;
private boolean inUse;
private static Singleton instance = new Singleton();
private Singleton()
{
v = new Vector();
inUse = true;
//
}
public static Singleton getInstance()
{
return instance;
}
}
但使用靜態變量也會存在問題
而且如在文章開頭提到的
好了是不是感覺單態模式根本沒法使用了
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27326.html