一、利用静态内部类实现单例模式(推荐)
package com.jsj; /** * Created by jsj on 2018/2/22. * 静态内部类在使用的时候才加载,且只加载一次 * 实现延迟加载和线程安全 */ public class Singleton2 { private static class T{ private static Singleton2 t=new Singleton2(); public static Singleton2 getInstance(){ return T.t; } } }
二、双重锁检查机制
package com.jsj; /** * Created by jsj on 2018/2/22. * 双重锁检查机制 * 单例模式 */ public class Singleton { private static volatile Singleton instance=null; private Singleton(){} public static Singleton getInstance(){ if(instance==null){//第一次判空,只有第一次实例化时才启用同步机制,提高性能 //假设线程A、B运行到此位置,B线程进入到同步块 synchronized (Singleton.class){ if(instance==null){//第二次判空,防止A线程再次创建实例(因为B线程已经创建了实例) //此操作不是原子操作,所以使用了volatile修饰instance,防止指令重排序 instance=new Singleton(); /* 此操作实际分为三步: (1)给对象分配内存空间; (2)对象初始化 (3)设置instance指向刚分配的内存地址 注:步骤(2)依赖于步骤(1),而步骤(2)(3)不存在依赖关系,JVM可针对它们进行指令的重排序优化, 使用volatile可防止指令的重排序 */ } } } return instance; } }