Java 单例模式

时间:2020-04-26
本文章向大家介绍Java 单例模式,主要包括Java 单例模式使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点

饿汉模式

不能惰性初始化,在JVM一开始就会被初始化,

public class HungrySingleton {
    //类加载时就初始化
    private static HungrySingleton instance = new HungrySingleton();

    private HungrySingleton() {
        System.out.println("HungrySingleton is created");
    }

    public void run() {
        System.out.println("HungrySingleton is running");
    }

    public static HungrySingleton getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        System.out.println("start");
        HungrySingleton.getInstance().run();
    }
}

懒汉模式

双重锁检查,避免在多线程情况下创建多个实例,但是如果单例类实现了java.io.Serializable接口,可能被反序列化,从而产生新的实例。

public class LazySingletonOne {
    private volatile static LazySingletonOne instance;

    private LazySingletonOne() {
        System.out.println(("LazySingletonOne is created"));
    }

    public void run() {
        System.out.println(("LazySingletonOne is running"));
    }

    public static LazySingletonOne getInstance() {
        if (instance == null) {
            synchronized (LazySingletonOne.class) {
                if (instance == null) {
                    instance = new LazySingletonOne();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        System.out.println("start");
        LazySingletonOne.getInstance().run();
    }
}

静态内部类

将单例类设置为final类型,能够禁止克隆的发生,同样静态内部类只有在第一次被引用时才加载,

public final class StaticNestedSingleton {
    // 声明为 final 能防止其在派生类中被 clone
    private StaticNestedSingleton() {
        System.out.println(("StaticNestedSingleton is created"));
    }

    public static StaticNestedSingleton getInstance() {
        return NestedClass.instance;
    }

    public void run() {
        System.out.println("run");
    }

    //在第一次被引用时被加载
    static class NestedClass {
        private static StaticNestedSingleton instance = new StaticNestedSingleton();
    }

    public static void main(String[] args) {
        System.out.println("start");
        StaticNestedSingleton.getInstance().run();
    }
}

枚举类模式

  • enum方法反序列化重新创建新的对象
  • 类的修饰abstract,所以没有办法实例化,反射也不行
  • 关于线程安全,是通过类加载机制来保证的,INSTANCE实例化的时机是在static块中,JVM加载类的过程是线程安全的。
public enum EnumSingleton {
    INSTANCE;
    private final String[] preference = {"intresting", "nice", "just so so"};

    public void printPreference() {
        System.out.println(Arrays.toString(preference));
    }
}

Java反编译查看

Compiled from "EnumSingleton.java"
public final class com.scxx.blackpanther.EnumSingleton extends java.lang.Enum<com.scxx.blackpanther.EnumSingleton> {
  public static final com.scxx.blackpanther.EnumSingleton INSTANCE;
  public static com.scxx.blackpanther.EnumSingleton[] values();
  public static com.scxx.blackpanther.EnumSingleton valueOf(java.lang.String);
  public void printPreference();
  static {};
}

scala实现单例模式

object在scala中被称作[单例对象]

object关键字创建了一个新的单例类型,就像一个class只有一个被命名的实例,如果你熟悉java,在scala中声明一个object就像创建了一个匿名类的实例。

object Singleton2Scala {
  def sum(l: List[Int]): Int = l.sum
}

原文地址:https://www.cnblogs.com/iFanLiwei/p/12782323.html