一、概述
1.单例模式的优点
由于单例模式只生成一个实例,减少了系统性能的开销,当一个对象的产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久助理内存的方式来解决。
2.单例模式的实现方式
(1)饿汉式
线程安全,调用效率高,不能延迟加载。
(2)懒汉式
线程安全,调用效率不高,可以延迟加载。
(3)静态内部类式
线程安全,调用效率高,可以延迟加载。
二、实现方式
1.饿汉式
饿汉式,static变量会在类装载时初始化,此时不会涉及多个线程多个线程对象访问该对象的问题。虚拟机保证只装载一次该类,肯定不会发生并发访问问题,因此可以省略sychronized关键字。
/* * 懒汉式 * 特点: 线程安全,调用效率高,不能延迟加载。 */ public class Singleton{ //类初始化时立即加载,由于加载类时是线程安全的 private static Singleton instance = new Singleton(); private Singleton(){ } //方法没有同步,调用效率高 public static Singleton getInstance(){ return instance; } }
测试
@Test public void testS1(){ Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2);//true }
2.懒汉式
因为每次调用getInstance()方法都要同步,并发效率低。
/* * 懒汉式 * 特点:线程安全,调用效率不高,可以延迟加载。 */ public class Singleton2{ private static Singleton2 instance; private Singleton2(){ } public static synchronized Singleton2 getInstance(){ if(instance == null){ instance = new Singleton2(); } return instance; } }
测试
@Test public void testS2(){ Singleton2 s1 = Singleton2.getInstance(); Singleton2 s2 = Singleton2.getInstance(); System.out.println(s1 == s2);//true }
3.静态内部类
/* * 静态内部类 */ public class Singleton3{ private Singleton3(){ } private static class SingletonInstance{ //保证内存在只有一个这样的实例 private static final Singleton3 instance = new Singleton3(); } public static Singleton3 getInstance(){ return SingletonInstance.instance; } }测试
@Test public void testS3(){ Singleton3 s1 = Singleton3.getInstance(); Singleton3 s2 = Singleton3.getInstance(); System.out.println(s1 == s2);//true }