什么时候使用单例模式

对于频繁创建和销毁对象,创建耗时过多或耗费资源过多(即:重量级对象),

但又经常用到的对象工具类对象,频繁访问数据库或文件的对象(如:数据源,session工厂等)时考虑使用单例模式

1.整个程序的运行只允许有一个类实例

2.需要频繁的创建和销毁对象

3.创建对象时耗时过多或耗资源过多

饿汉式

简单

稍微占用一些内存不过影响不大,如果确定这个实例一定会用到那就没有问题 可用

1
2
3
4
5
6
7
public class Singleton{
private static Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}

线程安全懒汉式

多线程时效率低 不推荐

1
2
3
4
5
6
7
8
9
10
public class Singleton{
private static Singleton INSTANCE;
private Singleton(){}
public static synchronized Singleton getSingleton(){
if(INSTANCE = null){
INSTANCE = new Singleton();
}
return INSTANCE;
}
}

懒汉式双重检查

同时解决了效率问题,而且实现了懒加载 可用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton{
private static volatile Singleton INSTANCE;
private Singleton(){}
public static Singleton getSingleton(){
if(INSTANCE = null){
      synchronized(Singleton.class){
if(INSTANCE = null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}

静态内部类方法

实现了懒加载,同时保证线程安全

利用了JVM加载类的时候只加载一次的机制,因此永远只有一个对象 完美的写法

1
2
3
4
5
6
7
8
9
pubic class Singleton{
private Singleton(){}
private static class SingletonHolder{
private final static Singleton INSTANCE = new Singleton();
}
public static Singleton getSingleton(){
return SingletonHolder.INSTANCE;
}
}

枚举法

最完美的写法 Effect Java作者Josh Bloch提倡的方式

不仅能避免多线程同步的问题,而且还能防止反序列化重新创建新的对象

1
2
3
4
public enum Singleton{
INSTANCE;
public void method(){}
}