目录
一、饿汉式
-
描述
- 顾名思义,急着用,也就是类加载的时候就实例化对象了。
-
实现
-
public class HungrySingleton { /** * 类加载的时候就实例化对象 */ private static HungrySingleton singleton = new HungrySingleton(); /** * 私有构造方法 */ private HungrySingleton(){ } /** * 返回实例对象的方法 * @return */ public static HungrySingleton getSingleton(){ return singleton; } public static void main(String[] args) { for (int i = 0; i < 20; i++) { new Thread(() -> { HungrySingleton singleton = HungrySingleton.getSingleton(); System.out.println(singleton); }).start(); } } }
-
优缺点
1.在类加载的时候就实例化对象,所以只实例化一次,保证了线程安全,性能比较好
2.没有实现延迟加载,长时间不适用的话,会占用内存,影响性能
二、懒汉式
-
描述
- 不着急使用,也就是需要用的时候再去实例化对象
-
实现
-
public class HoonSingleton { private static HoonSingleton singleton = null; private HoonSingleton(){ } /** * 使用的时候再实例化对象 * @return */ public static HoonSingleton getSingleton(){ if (null == singleton) { singleton = new HoonSingleton(); } return singleton; } public static void main(String[] args) { for (int i = 0; i < 20; i++) { new Thread(() -> { System.out.println(HoonSingleton.getSingleton()); }).start(); } } }
-
优缺点
- 实现了懒加载、性能良好,但是不能保证实例化对象的唯一性,所以线程不安全
三、双重校验(DCL模式)
-
描述
- 实际上就是实例化之前进行两次对象的非空校验
-
实现
-
public class DCL { private volatile static DCL singleton = null; private DCL(){ } /** * 核心代码 * @return */ public static DCL getSingleton(){ if (null == singleton) { synchronized(DCL.class) { if (null == singleton) { singleton = new DCL(); } } } return singleton; } public static void main(String[] args) { for (int i = 0; i < 20; i++) { new Thread(() -> { System.out.println(DCL.getSingleton()); }).start(); } } }
-
优缺点
- 性能比较好,实现了懒加载,保证了线程安全。但是可能存在因指令重排引起空指针异常
- 针对因指令重拍导致的空指针异常是可以使用volatile关键字解决。
-
private volatile static DCL singleton = null;
四、Holder模式(使用最多吧)
-
描述
- Holder模式实际上就是使用内部类的方式实现单例模式(有点类似结合饿汉模式和懒汉模式)
-
实现
-
public class HolderDemo { /** * 内部类 */ private static class Holder { private static HolderDemo singleton = new HolderDemo(); } public static HolderDemo getInstance(){ return Holder.singleton; } public static void main(String[] args) { for (int i = 0; i < 20; i++) { new Thread(() -> { System.out.println(HolderDemo.getInstance()); }).start(); } } }
-
优缺点
- 使用的时候才去实例化,实现了懒加载,性能好
- 在内部类中声明的实例对象,只实例化一次,保证了线程安全
五、枚举实现(感觉用的比较少)
-
描述
-
实现
-
public class EnumSingletonDemo {
private EnumSingletonDemo(){
}
//延迟加载
private enum EnumHolder{
INSTANCE;
private static EnumSingletonDemo instance=null;
private EnumSingletonDemo getInstance(){
instance=new EnumSingletonDemo();
return instance;
}
}//懒加载
public static EnumSingletonDemo getInstance(){
return EnumHolder.INSTANCE.instance;
}
}
-
优缺点
- 延迟加载、线程安全
以上就是单例模式的几种实现方式,不对之处还望指正。