单例模式 单例模式分为了饿汉式和懒汉式,总体来说懒汉式要优于饿汉式,饿汉式不管是否其他线程调用了getInstance,都在类加载阶段创建了实例。而懒汉式则只有在调用的时候,才实例化对象,更加节省系统资源。
饿汉式:
1 2 3 4 5 6 7 8 public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton () {} public static Singleton getInstance () { return INSTANCE; } }
懒汉式-双重检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class SingletonLazy { private static SingletonLazy instance = null ; private SingletonLazy () { } public static SingletonLazy getInstance () { if (instance == null ) { synchronized (SingletonLazy.class) { if (instance == null ) { instance = new SingletonLazy(); } } } return instance; } }
懒汉式-内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class SingletonLazy1 { private SingletonLazy1 () { } private static class InnerSingleton { private final static SingletonLazy1 instance = new SingletonLazy1(); } public static SingletonLazy1 getInstance () { return InnerSingleton.instance; } public static void helloworld () { System.out.println("hello lazy singleton." ); } }
执行Main方法测试,从输出结果看,只有执行了SingletonLazy1.getInstance()方法,才开始加载内部类SingletonLazy1$InnerSingleton。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Main { public static void main (String[] args) throws InterruptedException { SingletonLazy1.helloworld(); Object lock = new Object(); synchronized (lock) { lock.wait(1000 ); } System.out.println("分割线---------------" ); System.out.println(SingletonLazy1.getInstance()); } } 输出结果: [Loaded sun.nio.cs.US_ASCII$Decoder from /Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre/lib/rt.jar] 分割线--------------- [Loaded sun.misc.VMSupport from /Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre/lib/rt.jar] [Loaded com.wsy.learn.designmodel.SingletonLazy1$InnerSingleton from file:/Users/wangsiyuan1/workspace/springtest/target/classes/] com.wsy.learn.designmodel.SingletonLazy1@27716f 4