单例模式的几种实现
1. 懒汉式——多线程线程安全
package main.base.test.day20200518; public class LazySingleton { /** * 懒汉式 * * @author qianzi @date 2020-05-18 */ public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread:"+Thread.currentThread().getName()+" || "+LazySingleton.getInstance()); }).start(); } } //构造器私有化 private LazySingleton() { } //私有化静态变量 private static LazySingleton instance; //全局访问方法 public static LazySingleton getInstance() { if (null == instance) { return instance = new LazySingleton(); } return instance; } }
懒汉式在多线程下线程不安全
2. 懒汉式改进:加 sysnchronized (同步方法)——多线程线程安全
//全局访问方法 public static synchronized LazySingleton getInstance() { if (null == instance) { return instance = new LazySingleton(); } return instance; }
3. 懒汉式改进:双端校验锁机制——多线程线程安全
instance = new LazySingleton(); 在 即时编译、cpu优化 阶段可能被指令重排,加 volatile 防止指令重排
//私有化静态变量-加 volatile 防止指令重排 private static volatile LazySingleton instance; public static LazySingleton getInstance(){ if (null==instance){ synchronized (LazySingleton.class){ if (null==instance){ instance = new LazySingleton(); //字节码层面 2 3 即时编译、cpu优化 可能被指令重排 //1.分配空间 //2.初始化 //3.复制 } } } return instance; }
4. 饿汉式——线程安全(基于类加载机制保证)
package main.base.test.day20200518; public class HungrySingleton { public static void main(String[] args) { for (int i = 0; i <10 ; i++) { new Thread(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread:" + Thread.currentThread().getName() + " || " + HungrySingleton.getInstance()); }).start(); } } //构造器私有化 private HungrySingleton() { } //私有的静态成员变量 private static HungrySingleton instance = new HungrySingleton(); //全局调用的方法 public static HungrySingleton getInstance(){ return instance; } }
5.静态内部类方式——线程安全(基于类加载机制保证-延迟加载,调用时加载)
package main.base.test.day20200518; public class InnerClassSingleton { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread:" + Thread.currentThread().getName() + " || " + InnerClassSingleton.getInstance()); }).start(); } } //构造器私有化 private InnerClassSingleton() { } //私有静态成员变量 private static InnerClassSingleton instance; //私有静态内部类 private static class InnerClass { private static InnerClassSingleton instance = new InnerClassSingleton(); } //全局的静态方法 public static InnerClassSingleton getInstance() { return InnerClass.instance; } }
6. 枚举——线程安全
package main.base.test.day20200518; public enum EnumSingleton { INTANCE; } class EnumTest { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread:" + Thread.currentThread().getName() + " || " + EnumSingleton.INTANCE.hashCode()); }).start(); } } }