单例模式的使用场景
例如:数据源、session工厂
- 需要频繁的创建和销毁对象
- 经常需要使用的对象
- 创建的对象销毁过多的资源
- 工具类对象
饿汉式
静态常量
class Singleton {
//1. 构造器私有化, 外部不能new获取
private Singleton() {
}
//2.本类内部创建对象实例
private final static Singleton instance = new Singleton();
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}
静态代码块
class Singleton {
//1. 构造器私有化, 外部能new
private Singleton() {
}
//2.本类内部创建对象实例
private static Singleton instance;
static {
// 在静态代码块中,创建单例对象
instance = new Singleton();
}
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}
懒汉式
懒汉式(单线程内安全,多线程不安全)
class Singleton {
private static Singleton instance;
private Singleton() {
}
//提供一个静态的公有方法,当使用到该方法时,才去创建 instance
//即懒汉式
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式(线程安全,同步锁方法,但是效率低)
class Singleton {
private static Singleton instance;
private Singleton() {
}
//提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
//即懒汉式
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式(线程安全,双重检查instance变量是否已经实例化) volatile关键字 推荐的方法!
需要注意的是这里使用的volatile 关键字,如果没有线程共享volatile则多线程不安全
class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
//提供一个静态的公有方法,加入双重检查代码,解决线程安全问题, 同时解决懒加载问题
//同时保证了效率, 推荐使用
public static synchronized Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
懒汉式:静态内部类完成, 推荐使用
静态内部类SingletonInstance在调用getInstance方法是才会装载SingletonInstance,因此是安全的。
class Singleton {
//构造器私有化
private Singleton() {
}
//写一个静态内部类,该类中有一个静态属性 Singleton
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
//提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
枚举,可以实现单例, 推荐使用
enum Singleton {
INSTANCE; //属性
public void method() {
System.out.println("枚举调用方法");
}
}