Singleton Pattern says that just"define a class that has only one instance and provides a global point of access to it".
In other words, a class must ensure that only single instance should be created and single object can be used by all other classes.
单例模式的目的很简单,就是确保一个类只保有一个实例。为什么要只有一个实例呢,大体来说是“不能”和“不必”两种情况。关于“不能”,很熟悉的一个例子就是类锁,而“不必”更多考虑的是性能问题,如日志类,实例化太多浪费资源。
class Singleton {
public Singleton() {
System.out.println("ctor");
}
}
public class SingletonPattern {
public static void main(String[] args) {
Singleton singleton = new Singleton();
}
}
无法控制只实例化一个对象,因为构造函数是公开的,如果我不对外公开呢?
class Singleton {
private Singleton() {
System.out.println("ctor");
}
}
这么写问题就来了,没法用啊。也不尽然,Singleton
类里还是可以调用构造函数的。
class Singleton {
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
private Singleton() {
System.out.println("ctor");
}
private static Singleton singleton;
}
public class SingletonPattern {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
}
}
解决了,由于调用的时候才实例化,所有又称懒汉模式。(单线程的情况下
class Singleton {
public static Singleton getInstance() {
return singleton;
}
private Singleton() {
System.out.println("ctor");
}
private static Singleton singleton = new Singleton();
}
这下多线程也安全了,但是类加载的时候就会初始化,造成内存浪费,对应被称为饿汉模式。
class Singleton {
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
return singleton;
}
private Singleton() {
System.out.println("ctor");
}
private volatile static Singleton singleton;
}
这么写感觉套娃了,并且同步也会造成性能的降低。
class Singleton {
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
private Singleton() {
System.out.println("ctor");
}
private volatile static Singleton singleton;
}
可以用双检查锁解决同步等待的问题。
网友评论