设计模式之单例模式领略

界说:Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。)

1.饿汉式

public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return INSTANCE; } public void method(){ System.out.println("普通要领"); } public static void main(String[] args) { Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println(instance1 == instance2); } }

此种方法在事情中最为简朴常用。类加载到内存后,就只被实例化一次,所以只会发生一个实例,JVM担保线程安详。独一的缺点是不管用到与否,城市在类加载的时候完成实例化。

2.懒汉式

public class SingletonLazy { private static volatile SingletonLazy INSTANCE; private SingletonLazy(){} public static SingletonLazy getInstance(){ if (INSTANCE == null){ synchronized (Singleton.class){ if (INSTANCE == null){ INSTANCE = new SingletonLazy(); } } } return INSTANCE; } public void method(){ System.out.println("普通要领"); } public static void main(String[] args) { for (int i = 0; i < 10; i++) { SingletonLazy instance = SingletonLazy.getInstance(); new Thread(()-> System.out.println(instance.hashCode())).start(); } } }

此种方法固然到达了按需初始化的目标,可是带来了线程不安详的问题,所以通过加锁的方法办理,可是又带来效率下降的问题,别的变量需要添加volatile要害字,防备指令重排序。

3.静态内部类

public class SingletonInner { private SingletonInner(){} private static class SingletonInnerHolder{ private static final SingletonInner INSTANCE = new SingletonInner(); } public static SingletonInner getInstance(){ return SingletonInnerHolder.INSTANCE; } public void method(){ System.out.println("普通要领"); } public static void main(String[] args) { for (int i = 0; i < 10; i++) { SingletonInner instance = SingletonInner.getInstance(); new Thread(()-> System.out.println(instance.hashCode())).start(); } } }

此种方法办理了上面两种方法的问题,当SingletonInner类被加载的时候,SingletonInnerHolder内部类是不会被加载的,只有在挪用getInstance()的时候才会被加载,既到达了懒加载,又担保了只有一个实例。

4.列举方法

public enum SingletonEnum { INSTANCE; public void method(){ System.out.println("普通要领"); } public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(()-> System.out.println(SingletonEnum.INSTANCE.hashCode())).start(); } } }

此种方法不只可以办理线程同步问题,还可以防备反序列化,因为列举类没有结构要领。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsdjfg.html