单例模式
饿汉式
-
最经典的饿汉式写法
-
//普通的单例设计模式 public class Hungry { public static void main(String[] args) { Man1.getInstance(); } } class Man1{ private Man1(){} private static final Man1 instance = new Man1(); public static Man1 getInstance(){ return instance; } }
-
-
静态代码块饿汉式单例模式
-
package singleton.hungry; //饿汉式单例设计模式,运用静态代码块的方法 public class HungryStaticBlock { public static void main(String[] args) { Man3 instance = Man3.getInstance(); Man3 instance1 = Man3.getInstance(); System.out.println(instance==instance1); } } class Man3{ private Man3(){} private static Man3 m3; static{ Man3 m3 = new Man3(); System.out.println(m3); } public static Man3 getInstance(){ return m3; } }
-
懒汉式
-
线程不安全的
-
/* 线程不安全,可能会导致出现多个实例,不可用 */ public class LazyUnsafe1 { public static void main(String[] args) { Man2 instance1 = Man2.getInstance(); Man2 instance2 = Man2.getInstance(); System.out.println(instance1==instance2); } } class Man2{ private Man2(){} private static Man2 instance = null; public static Man2 getInstance(){ if (instance==null){ instance = new Man2(); } return instance; } }
-
-
线程安全但是效率低(synchronized)
-
/* 线程安全的,但是效率有点低,实际开发不推荐 */ public class LazySafe1 { public static void main(String[] args) { } } class Man4{ private Man4(){} private static Man4 instance = null; public synchronized static Man4 getInstance(){ if (instance==null){ instance = new Man4(); } return instance; } }
-
-
双重检查(推荐)
-
import com.sun.javafx.scene.input.InputEventUtils; /* 双重检查,效率要比LazySafe1直接加synchronized高 */ public class LazySafe2 { } class Man6{ private Man6(){} private static Man6 instance = null; public static Man6 getInstance(){ if (instance == null){ synchronized (Man6.class){ if (instance==null){ instance = new Man6(); } } } return instance; } }
-
-
静态内部类方式(推荐)
-
/** * 静态内部类实现懒汉式单例模式 * 推荐使用 */ public class LazySafe3 { public static void main(String[] args) { } } class Man7{ private Man7(){} private static class tool{ public static final Man7 instance = new Man7(); } public synchronized static Man7 getInstance(){ return tool.instance; } }
-
只有在Man7调用getInstance方法的时候才会装载tool静态内部类,类的加载机制导致了这是线程安全的,所以getInstance这个方法前的synchronized加不加都行
-
-
枚举类(官方推荐)
-
/** * 枚举类实现单例模式懒汉式 * 官方推荐使用 */ public class LazySafe4 { public static void main(String[] args) { Man8 instance1 = Man8.INSTANCE; Man8 instance2 = Man8.INSTANCE; instance1.sayOk(); System.out.println(instance1==instance2); } } enum Man8{ INSTANCE; public void sayOk(){ System.out.println("ok"); } }
-
在jdk源码中的应用:
- Runtime类
- 饿汉式单例设计模式