我们可以在Java中打破单例模式的不同方法有哪些.我知道一种方式,即如果我们不在单例中同步方法,那么我们可以创建多个类的实例.因此应用同步.有没有办法打破单例java类.
public class Singleton {
private static Singleton singleInstance;
private Singleton() {
}
public static Singleton getSingleInstance() {
if (singleInstance == null) {
synchronized (Singleton.class) {
if (singleInstance == null) {
singleInstance = new Singleton();
}
}
}
return singleInstance;
}
}
Run Code Online (Sandbox Code Playgroud)
Sat*_*eri 10
从您给定的代码开始,"Double-Checked Locking"可能会在某些环境中被破坏,当使用Symantec JIT在系统上运行时,它不起作用.特别是Symantec JIT编译
singletons[i].reference = new Singleton();
Run Code Online (Sandbox Code Playgroud)
以下(注意Symantec JIT使用基于句柄的对象分配系统).
0206106A mov eax,0F97E78h
0206106F call 01F6B210 ; allocate space for
; Singleton, return result in eax
02061074 mov dword ptr [ebp],eax ; EBP is &singletons[i].reference
; store the unconstructed object here.
02061077 mov ecx,dword ptr [eax] ; dereference the handle to
; get the raw pointer
02061079 mov dword ptr [ecx],100h ; Next 4 lines are
0206107F mov dword ptr [ecx+4],200h ; Singleton's inlined constructor
02061086 mov dword ptr [ecx+8],400h
0206108D mov dword ptr [ecx+0Ch],0F84030h
Run Code Online (Sandbox Code Playgroud)
如您所见,在调用Singleton的构造函数之前执行对singletons [i] .reference的赋值.这在现有Java内存模型下是完全合法的,并且在C和C++中也是合法的(因为它们都没有内存模型).
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
除此之外
SerializableReflection(我相信)*你如何解决违规者?
readResolve()类中的方法并抛出异常clone()并抛出CloneNotSupported异常例
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
// Check if we already have an instance
if (INSTANCE != null) {
throw new IllegalStateException("Singleton" +
" instance already created.");
}
}
public static final Singleton getInstance() {
return INSTANCE;
}
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
private Object writeReplace() throws ObjectStreamException {
return INSTANCE;
}
public Object clone() throws CloneNotSupportedException {
// return INSTANCE
throw new CloneNotSupportedException();
}
}
Run Code Online (Sandbox Code Playgroud)
毕竟我建议使用Enum作为Singleton最安全的方法(因为java5最好的方法是使用枚举)
public static enum SingletonFactory {
INSTANCE;
public static SingletonFactory getInstance() {
return INSTANCE;
}
}
Run Code Online (Sandbox Code Playgroud)
多线程是单例的最大问题。您可以通过同步或使用急切初始化来避免这种情况。
另一种方法是在不应该使用的地方使用单例。通过使用单例模式,您可能会以阻碍程序后续开发的方式应用它。(例如,在游戏中创建一个单例“玩家”,因为您假设它是单人游戏。开发的下一步“添加合作功能”)。
单例模式有它的优点,但不要在没有仔细考虑的情况下使用它。
| 归档时间: |
|
| 查看次数: |
24290 次 |
| 最近记录: |