单例模式的六种写法
重新回顾一下设计模式中的单例模式。
单例模式就是保证一个类只有一个实例,并提供一个访问它的全局访问点。使用场景:
- 整个项目需要一个共享访问点或共享数据。
- 创建一个对象需要耗费的资源过多,比如访问i/o或者数据库等资源。
- 工具类对象。
单例模式有很多种写法,最常见有六种写法。
1.饿汉式
public class singleton {
//饿汉式
private singleton(){
}
private static singleton instance = new singleton();
public static singleton getinstance(){
return instance;
}
}
优点:取对象的速度快;避免了多线程同步问题。
缺点:因为在类加载时就已经初始化,所以类加载较慢;容易造成内存浪费。
2.懒汉式(线程不安全)
public class singleton {
//懒汉式(线程不安全)
private singleton(){
}
private static singleton instance;
public static singleton getinstance(){
if (instance == null) {
instance = new singleton();
}
return instance;
}
}
优点:在第一次调用时才会初始化,不会造成内存浪费。
缺点:获取对象速度较慢;多线程是不安全;
3.懒汉式(线程安全)
public class singleton {
//懒汉式(线程安全)
private singleton(){
}
private static singleton instance;
public static synchronized singleton getinstance(){
if (instance == null) {
instance = new singleton();
}
return instance;
}
}
优点:线程安全;不会造成内存浪费;
缺点:每次调用方法getinstance()时都要进行同步,造成不必要的开销。
4.双重检查模式(dcl)
public class singleton {
private singleton(){
}
private static volatile singleton instance;
public static singleton getinstance(){
if (instance == null) {
synchronized (singleton.class){
if (instance == null) {
instance = new singleton();
}
}
}
return instance;
}
}
优点:只有第一次获取对象是才会进行同步,资源利用高;
缺点:第一次加载是较慢;高并发环境会存在dcl失效问题;
5.静态内部类模式
public class singleton {
private singleton(){
}
private static class singletonhodler{
private static final singleton instance = new singleton();
}
public static singleton getinstance(){
return singletonhodler.instance;
}
}
优点:第一次调用getinstance()方法时才会加载类singletonhodler并初始化singleton 对象,既确保线程安全,又保证singleton类的唯一性。所以写单例模式时推荐使用这种模式。
6.枚举
public enum singleton {
instance;
public void todo(){
}
}
优点:简单;线程安全。
缺点:代码可读性低。
总结以上6种单例模式的写法,推荐使用静态内部类单例模式。