栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式之禅(一):单例模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式之禅(一):单例模式

大家好,我是河海哥,专注于后端,如果可以的话,想做一名code designer而不是普通的coder,一起见证河海哥的成长,您的评论与赞是我的最大动力。

从今天开始就得把设计模式好好弄一弄了,不懂设计模式,看源码一定会是一个遗憾吧,所以先把常用的设计模式好好整理,好好理解。正好边读《设计模式之蝉》边自己总结,

1-1:饿汉
public class Singleton1 {
    public static final Singleton1 object = new Singleton1();

    private Singleton1() {

    }

    public static Singleton1 getInstance() {
        return object;
    }

    public void doSomething() {
        System.out.println("do something");
    }
}

代码很好理解。

  • 优点:不会有线程安全问题,因为当类加载的时候他的静态变量会被初始化,这个过程是线程安全的。
  • 缺点:如果这种单例多了,当项目起来的时候就会造成很多个单例对象进入内存,启动起来就慢了,其实也问题不大,因为运行好就行。
1-2:懒汉

懒汉的意思就是在需要这个对象的时候,将这个对象丢进内存里面,供别人调用。

1-2-1:有问题的懒汉
package com.company.design.singleton;


public class Singleton2 {
    public static Singleton2 object = null;

    private Singleton2() {

    }

    public static Singleton2 getInstance() {
        if (object == null) {
            object = new Singleton2();
        }
        return object;
    }
}

问题主要是并发的时候,两个线程同时判断object==null,就会同时new两个object对象。

1-2-1:并发性能差的懒汉

为了实现互斥,添加synchronized 进方法,就可以实现只有一个线程能执行该方法。但是,这对并发效率会影响。

package com.company.design.singleton;


public class Singleton3 {
    public static Singleton3 object = null;

    private Singleton3() {

    }

    public synchronized static Singleton3 getInstance() {
        if (object == null) {
            object = new Singleton3();
        }
        return object;
    }
}
1-2-2:DCL双重检测锁
package com.company.design.singleton;


public class Singleton4 {
    public static Singleton4 object = null;

    private Singleton4() {

    }

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

因为并发的时候,只有一开始当object==null的时候,同时对object进行判断,才会有并发问题,只要过了这个时候object不为空刷新回主存,就不存在并发问题了。所以只需要对这么一会儿进行限制。而不是向上一个那样,对getInstance 这个方法全程限制并发。
同时,这个同步锁范围是这个类,进行了两次(object == null)的判定,所以就叫DCL。因为没有后一次的判定,仍然会出现多个对象的情况。ps:以前觉得这种做法很不好,觉得多余,经过两年现在在看,直接妙不可言ok?spring的单例bean里面也用到了这种提高并发的处理,但是不是用的这种单例方式,而是注册表将创建好的bean放在一起,通过注册表来实现单例的效果。

1-2-3:静态内部类(没用过)

也是一种单例的方式。

package com.company.design.singleton;


public class Singleton5 {

    private Singleton5() {

    }

    public Singleton5 getInstance() {
        return InstanceHolder.instance;
    }

    public static class InstanceHolder {
        private static final Singleton5 instance = new Singleton5();
    }
}
枚举

还没见过枚举的单例,就当是一种写法储存吧。怎么感觉有点像回字有几种写法。。

1-3:总结:

学了一点单例的写法,主要还是DCL的优势,以及简单看了下spring的一点点源码,先弄完设计模式,之后再读spring源码读设计应该会很好吧,期待ing。加油。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/396846.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号