单例模式
这种模式只涉及到一个单一的类,该类只负责创建一个自己的对象,并且确保只有单个对象被创建,还提供有一个可访问唯一对象的方法。
注意:
单例类必须自己创建一个唯一的实例
单例类必须给所有对象提供一个访问该类的唯一实例的方法。
饿汉模式
- 饿汉模式即在程序初始化时,就将该单例创建好,后续需要时直 接使用。
public class SingleObject {
private static SingleObjectinstance =new SingleObject();
//私有化构造函数
private SingleObject() {}
//获取示例方法
public static SingleObjectgetInstance() {
return instance;
}
public void innerMethod() {
System.out.println("Hellow world~!");
}
}
懒汉模式
- 懒汉模式即在需要使用时,才初始化该实例并且使用,但是存在线程安全问题
public class SingleObject1 {
private static SingleObject1instance;
private SingleObject1() {}
public static SingleObject1getInstance() {
if (instance ==null) {
instance =new SingleObject1();
}
return instance;
}
}
懒汉模式--线程安全
- 使用 synchronized 关键字对方法加锁,确保线程安全。但也大大的降低了速度。
public class SingleObject1 {
private static SingleObject1instance;
private SingleObject1() {}
public static synchronized SingleObject1getInstance() {
if (instance ==null) {
instance =new SingleObject1();
}
return instance;
}
}
}
懒汉模式--双重加锁
获取实例时,先进行对象判空。如果为空,对单例类进行加锁。再进行一次判空,如果为空初始化实例。
volatile 关键字实现了可见性,在实例被初始化后。下一个线程进行判空时,则该实例已经是不为空了。
满足了线程安全,并且不影响速度。
public class SingleObject1 {
// volatile 满足了可见性。初始化后马上可见
private volatile static SingleObject1instance;
private SingleObject1() {}
// 双重锁
public static SingleObject1getInstance() {
if (instance ==null) {
synchronized (SingleObject1.class){
if (instance ==null) {
instance =new SingleObject1();
}
}
}
return instance;
}
}