一、单例模式
1、什么是单例模式
采用单例模式创建的类,无论程序如何运行,只会有一个实例会对象产生。
2、如何实现单例模式
把握三个原则:
(1)构造方法私有化。
(2)类内部需自己实例化对象。
(3)提供公有的方法返回该实例化对象。
外部想要拿到该类的实例化对象则必须通过该公有方法的返回(实际上,java可以通过反射机制是能够实例化构造方法是私有化的类的,这会导致所有模式的单例模式失效,这里 暂不做讨论)。
(1)饿汉模式
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
饿汉模式,即在类创建的同时就把该类实例化了,这可能会导致资源浪费,因为有可能不会用到该类的实例化对象,但是该模式是线程安全的。
(2)懒汉模式
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
懒汉模式,是在第一次调用返回实例化对象的公有方法的时候才会去创建,但这不是线程安全的,因为有可能两个线程同时调用该方法。
可以在方法上加锁(synchronized):
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
或者:
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
只在实例化对象为空时才会进入同步,效率稍微比在方法外面加同步修饰高一点。
但是这样同样会造成一定资源的浪费,因为大多数情况下并不会出现线程安全问题。