Java 单例设计模式实现
Java Singleton Design Pattern implementation
Singleton class 的实现是否可以像下面这样简单:
public class MyClass {
private final static MyClass myClass = new MyClass();
private MyClass() {}
public static MyClass getInstance() {
return myClass;
}
}
结束:
public class MyClass {
private final static MyClass myClass;
private MyClass() {}
public static MyClass getInstance() {
if(null == myClass) {
myClass = new MyClass();
}
return myClass;
}
}
以上实现中哪个更好,为什么?
我观察到的一件事是,对于上面的第一个实现,如果有的话,对象构造函数在静态块之前被调用。
此外,如果有第二个实现的线程安全版本(可能是双空检查和同步块),应该首选哪个?
是的。您 可以 使用第一个版本,但我建议您使用 enum
。维基百科在 Singleton
上的条目说
In the second edition of his book Effective Java, Joshua Bloch claims that a single-element enum type is the best way to implement a singleton for any Java that supports enums.
类似
public enum Singleton {
INSTANCE;
}
yoy 需要注意定义单例的原则规则 class 是:
- 私有构造函数 - 限制其他 classes
的对象创建
- 私有静态字段变量,其中包含相同的唯一实例class
- 一个 public 静态方法,在请求时用于 return 此实例
这取决于你想要它的方式,你是想要早期初始化还是延迟初始化。第一个是早期初始化的例子,而第二个是延迟初始化的例子。有多种方法可以定义一个完美的单例Class
我想简单介绍一下单例设计模式。
你的第一个代码片段
public class MyClass {
private final static MyClass myClass = new MyClass();
public static MyClass getInstance() {
return myClass;
}
}
上述方法工作正常但有缺点,因为实例在实际需要它之前就已经创建了很多,所以在 运行-time 想想如果实例不大你可以保留它的情况未使用,但如果它很大,那么创建 instance.This 方法的目的是什么,称为 Eager initialization
下面显示的代码表示第二种方法称为延迟初始化
public class MyClass {
private final static MyClass myClass;
public static MyClass getInstance() {
if(null == myClass) {
myClass = new MyClass();
}
return myClass;
}
}
但是你的代码又存在一个缺陷,让我们了解一下上面代码中的缺陷
假设我们有两个线程,即 T1 和 T2,两个线程都旨在创建实例并执行检查 null == myClass,现在两个线程都已识别实例变量为 null 因此假设他们必须创建一个实例。他们依次进入同步块并创建实例。最后,我们的应用程序中有两个实例。
这可以通过简单地双重检查锁定来解决。下面的代码将向您展示更好的实现方式。请注意-我在代码中使用了私有构造函数。
public class MyClass {
private final static MyClass myClass = null;
//private constructor
private MyClass(){
}
public static MyClass getInstance() {
if(myClass == null) {
synchronized (MyClass.class){
// Double check
if(myClass == null){
myClass = new MyClass();
}
}
}
return myClass;
}
}
Singleton class 的实现是否可以像下面这样简单:
public class MyClass {
private final static MyClass myClass = new MyClass();
private MyClass() {}
public static MyClass getInstance() {
return myClass;
}
}
结束:
public class MyClass {
private final static MyClass myClass;
private MyClass() {}
public static MyClass getInstance() {
if(null == myClass) {
myClass = new MyClass();
}
return myClass;
}
}
以上实现中哪个更好,为什么?
我观察到的一件事是,对于上面的第一个实现,如果有的话,对象构造函数在静态块之前被调用。
此外,如果有第二个实现的线程安全版本(可能是双空检查和同步块),应该首选哪个?
是的。您 可以 使用第一个版本,但我建议您使用 enum
。维基百科在 Singleton
上的条目说
In the second edition of his book Effective Java, Joshua Bloch claims that a single-element enum type is the best way to implement a singleton for any Java that supports enums.
类似
public enum Singleton {
INSTANCE;
}
yoy 需要注意定义单例的原则规则 class 是:
- 私有构造函数 - 限制其他 classes 的对象创建
- 私有静态字段变量,其中包含相同的唯一实例class
- 一个 public 静态方法,在请求时用于 return 此实例
这取决于你想要它的方式,你是想要早期初始化还是延迟初始化。第一个是早期初始化的例子,而第二个是延迟初始化的例子。有多种方法可以定义一个完美的单例Class
我想简单介绍一下单例设计模式。
你的第一个代码片段
public class MyClass {
private final static MyClass myClass = new MyClass();
public static MyClass getInstance() {
return myClass;
}
}
上述方法工作正常但有缺点,因为实例在实际需要它之前就已经创建了很多,所以在 运行-time 想想如果实例不大你可以保留它的情况未使用,但如果它很大,那么创建 instance.This 方法的目的是什么,称为 Eager initialization
下面显示的代码表示第二种方法称为延迟初始化 public class MyClass {
private final static MyClass myClass;
public static MyClass getInstance() {
if(null == myClass) {
myClass = new MyClass();
}
return myClass;
}
}
但是你的代码又存在一个缺陷,让我们了解一下上面代码中的缺陷
假设我们有两个线程,即 T1 和 T2,两个线程都旨在创建实例并执行检查 null == myClass,现在两个线程都已识别实例变量为 null 因此假设他们必须创建一个实例。他们依次进入同步块并创建实例。最后,我们的应用程序中有两个实例。
这可以通过简单地双重检查锁定来解决。下面的代码将向您展示更好的实现方式。请注意-我在代码中使用了私有构造函数。
public class MyClass {
private final static MyClass myClass = null;
//private constructor
private MyClass(){
}
public static MyClass getInstance() {
if(myClass == null) {
synchronized (MyClass.class){
// Double check
if(myClass == null){
myClass = new MyClass();
}
}
}
return myClass;
}
}