单例模式

单例模式

属于创建型模式

单例模式,就是采取一定的方法保证在整个系统中,对于某个类,只存在一个实例对象.

为什么使用单例模式

  1. 使用单例模式,对于那些经常使用的实例, 可以减少创建对象的开销
  2. 实例化减少,可能减少虚拟机垃圾回收的压力

使用单例模式的几种方法

静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton {
//静态变量
private static Singleton instance;

//私有化构造器, 防止外部进行new
private Singleton(){}

//synchronized保证线程安全性, 但是会影响效率,存在实例时也要进行同步, 这是不必要的
public static synchronized Singleton getInstance(){
if (instance!=null){
return instance;
}else{
return instance=new Singleton();
}
}
}

双重检查

在静态方法保证线程安全的基础上,提高了系统效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class DoubleCheck {
// 保证可见性,一但有实例时,所有线程都会知道
private static volatile DoubleCheck instance;

private DoubleCheck(){}

private static DoubleCheck getInstance(){
if (instance==null){
synchronized (DoubleCheck.class){
if (instance==null){
return instance=new DoubleCheck();
}
}
}
return instance;
}
}

静态内部类

比较推荐的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class StaticInnerClass {
private StaticInnerClass() {
}
// 类装载时,静态内部类不会被加载, 保证了懒加载
// 静态内部类装载时, JVM提供了线程安全, 保证了线程安全
// 类的静态属性,只在类装载时被加载,保证了单例
private static class StaticInnerClassIntance {
private static final StaticInnerClass INTANCE = new StaticInnerClass();
}

public static StaticInnerClass getInstance() {
return StaticInnerClassIntance.INTANCE;
}
}

枚举方法

1
2
3
4
5
6
7
public enum EnumSingleton {
INSTACNE;

public static EnumSingleton getIntance(){
return INSTACNE;
}
}

枚举方法是最好的一种,也是官方推荐的一种, 它完美的解决了懒加载, 线程安全, 单例等问题

而且他不会被反射影响, 上面几种方法都可以通过反射的方式, 破坏单例, 而枚举类型是无法通过反射创建实例的