was修改类加载模式_设计模式java语言实现之单例模式

f054041b41d18126b4d0044e4a316b5e.png

设计模式java语言实现之单例模式

前言:

作者:韩数
Github: https:// github.com/hanshuaikang
时间:2019-01-26
Jdk版本:1.8

定义:

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

适用范围:

一个全局使用的类频繁地创建与销毁。当某些如打印机程序只需要一个操作实例的时候(多个实例同时调用一台打印机打印文件可能会出现问题)

优/缺点

优点:
在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
避免对资源的多重占用(比如写文件操作)
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化

前提引入:

单例模式是设计模式中较为简单的设计模式之一,同时又在实际的开发过程中广泛使用的一种设计模式,本次,我们将从基础版开始,使用4种不同的方式来实现单例模式。

代码实战:

1.基础版

这种方式实现的单例模式是我们日常使用较多的设计模式,采用了延迟加载来减少系统资源不必要的开支,但如果多个线程同时调用 getInstance 方法获取Singleton的实例时,可能会出现问题。

优/缺点:

优点:易于实现
缺点:线程不安全,在多线程下不能正常工作

代码如下:

/***
 * 
 * @author 韩数
 * 一般单例模式实现,采用延迟加载方式实现
 *
 */

public class Singleton {

    private static Singleton uniqueInstance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

}

2.线程安全基础版:

代码如下:

优/缺点:

优点:线程安全,没有加锁,执行效率会高一点
缺点:容易产生垃圾对象,类加载时就初始化,浪费内存
/***
 * 
 * @author 韩数
 * 常用的单例模式实现
 * 线程安全,不足之处,可能会损失一部分性能,非延迟加载
 *     
 */


public class Singleton {

    //在类初始化的时候就实例化对象,所以不存在多线程的安全问题
    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return uniqueInstance;
    }
}

3.线程安全加强版:

优/缺点:

优点:线程安全,延迟加载
缺点:必须加锁,效率比较低

代码如下:

/**
 * 
 * @author 韩数
 * 线程安全方式实现单例模式,缺点是,每次都会调用synchronized的关键字修饰的方法,会损失一定的性能
 *
 */

public class Singleton {


    private static Singleton uniqueInstance;

    private Singleton() {}

    //synchronized修饰该方法,保证每次只有一个线程进入该方法,从而避免产生多个Singleton对象实例。
    public static synchronized Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

4.线程安全旗舰版:

双检锁/双重校验锁(DCL,即 double-checked locking): 可以在保证安全性的情况下,兼顾高性能

优/缺点:

优点:线程安全,延迟加载,执行效率高
缺点:实现难度比前几种稍显复杂

关于 volatile 关键字,感兴趣的伙伴可以去这个博客看一下,写得非常好

https://www.cnblogs.com/dolphin0520/p/3920373.html

代码如下:

/***
 * 
 * @author 韩数
 * 线程安全,延迟加载方式实现单例模式
 *
 */

public class Singleton {

    private volatile static Singleton uniqueInstance;

    // 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
    //保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是       立即可见的。
    //禁止进行指令重排序。

    private Singleton() {}

    public static Singleton getInstance() {
        //延迟加载
        if (uniqueInstance == null) {
            //加线程锁
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

总结:

本篇文章较为简单的阐述了单例模式的优缺点,使用场景,以及4种不同的实现方式,当然,现实生活中,单例模式的实现绝非只有本文中的4种,如果对单例模式的其他实现方式感兴趣的话,大家可以去互联网上查询相关的资料。

写在最后:

欢迎大家给小星星,您的星星是我写下去的不竭动力!

源码部分请移步本人Github下载:

Github地址:

Github:https://github.com/hanshuaikang/design-pattern-java

参考资料:

菜鸟教程:http://www.runoob.com/design-pattern/strategy-pattern.html

Head frist of 设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值