单例模式
Java中的设计模式总结来说至少有23种,而单例模式是其中最简单且最常用的设计模式之一。
单例模式有两种常见的类型,一种是饿汉式,一种是懒汉式。
单例模式的特点
1. 单例类只能有一个实例并且由自己创建
2. 单例类必须给其他所有对象提供这一实例
单例模式的应用场景
无论是应用层软件或者是底层服务,经常需要用到单例模式的特点,比如线程池,缓存,日志,对话框,打印机的驱动程序等等。
懒汉式单例模式
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
为了避免单例类被外部直接new出来,应当把构造方法私有化,只能通过getInstance()来访问。虽然实际上即使通过构造方法私有化,在外部仍然可以通过反射等手段创建出这个类的对象。不过这个问题在此不深入探讨,有兴趣的朋友可以了解下Java的反射机制。
以上的代码在多线程操作的过程中仍然可能出现问题,解决方法是加上同步操作。
代码如下:
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
但是实际上面这种加上同步的方法效率比较低,因为无论哪个线程getInstance的时候都会进行同步,因此最好是当实例已经存在的时候直接返回而不加同步,若不存在需要创建的时候再进行同步,因此优化后的代码如下:
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
饿汉式模式
所谓饿汉式即在类创建的时候就同时new出来一个静态的实例,供外部使用,因此保证线程安全。
代码如下:
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}