手机版
你好,游客 登录 注册 搜索
背景:
阅读新闻

设计模式之单例模式理解

[日期:2020-03-29] 来源:cnblogs.com/tobyhomels  作者:tobyhomels [字体: ]

定义: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();
        }
    }
}

此种方式不仅可以解决线程同步问题,还可以防止反序列化,因为枚举类没有构造方法。

 

linux
相关资讯       单例模式  设计模式 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删��其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款