单例设计模式
Java中单例模式是一种常见的设计模式
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
本文写了两种经典方式:饿汉式和懒汉式,其中饿汉式是线程安全的,而懒汉式是线程不安全的
懒汉式单例
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
// 指向自己实例的私有静态引用
// 使用静态变量是因为在静态方法中无法访问非静态方法和非静态变量
private static Singleton single=null;
// 私有的构造方法
private Singleton() {
}
// 以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
实现线程安全的懒汉式
1)、同步延迟加载 — synchronized方法
// 线程安全的懒汉式单例
public class Singleton {
private static Singleton singleton;
private Singleton(){}
// 使用 synchronized 修饰,临界资源的同步互斥访问
public static synchronized Singleton getSingleton2(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
2)、同步延迟加载 — synchronized块
// 线程安全的懒汉式单例
public class Singleton {
private static Singleton2 singleton2;
private Singleton(){}
public static Singleton getSingleton2(){
synchronized(Singleton.class){ // 使用 synchronized 块,临界资源的同步互斥访问
if (singleton == null) {
singleton = new Singleton();
}
}
return singleton;
}
}
3)、同步延迟加载 — 使用内部类实现延迟加载
// 线程安全的懒汉式单例
public class Singleton {
// 私有内部类,按需加载,用时加载,也就是延迟加载
private static class Holder {
private static Singleton singleton = new Singleton();
}
private Singleton() {
}
public static Singleton5 getSingleton5() {
return Holder.singleton5;
}
}
单例模式与双重检查(Double-Check idiom)
// 线程安全的懒汉式单例
public class Singleton {
//使用volatile关键字防止重排序,因为 new Instance()是一个非原子操作,可能创建一个不完整的实例
private static volatile Singleton singleton;
private Singleton() {
}
public static Singleton getSingleton() {
// Double-Check idiom
if (singleton == null) {
synchronized (Singleton.class) { // 1
// 只需在第一次创建实例时才同步
if (singleton == null) { // 2
singleton = new Singleton3(); // 3
}
}
}
return singleton;
}
}
饿汉式单例
// 饿汉式单例
public class Singleton {
// 指向自己实例的私有静态引用,主动创建
private static Singleton1 singleton1 = new Singleton1();
// 私有的构造方法
private Singleton(){}
// 以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton getSingleton(){
return singleton;
}
}