深入浅出设计模式之单例设计模式

引子

开发中很多对象哦我们只需要一个,比方说:线程池,缓存,对话框,注册表对象等。如果制造出多个实例,会导致许多问题产生。没错,这就是单例模式,相信大家或多或少都听说过单例模式。

定义

确保一个类只有一个实例,并提供一个全局的访问点。

单例模式只有一个一个类,听起来很简单,但是实现起来会有很多问题。

尝试1

延迟实例化:

public class Singleton {
    private static Singleton uniqueInstance;

    //私有化构造
    private Singleton(){}

    public static Singleton getInstance(){
        //判断是否创建
        if(uniqueInstance==null){
            uniqueInstance=new Singleton();
        }
        //返回
        return uniqueInstance;
    }
}

1.完成了私有化构造器
2.判断单例是否创建
3.取出单利

好处:和全局变量一样,多了个优点:单件可以延迟实例化。
问题:产生问题,用多线程模拟出错误。

尝试2

解决方法,用同步关键字:

public class Singleton {
    private static Singleton uniqueInstance;

    //私有化构造
    private Singleton(){}

    //加入同步
    public static synchronized Singleton getInstance(){
        //判断是否创建
        if(uniqueInstance==null){
            uniqueInstance=new Singleton();
        }
        //返回
        return uniqueInstance;
    }
}

优点:解决了多线程产生的问题
缺点:只需要第一次同步,和直接用同步会降低性能,当创建好对象后,每次调用这个方法,同步都是一种累赘。

那到底应该用哪种方法来解决存在的问题呢?让我们看看我们有几种选择?

改善多线程的几种选择:

1.这个getInstance()的同步性能对应用程序不是很关键

这种情况意味着我们的程序里使用getInstance()的地方很少,或者是你不在乎同步关键字产生的效率问题,那么就直接使用有同步关键字的单例吧。

2.使用“急切”创建实例,而不用延迟实例化的做法

如果程序总是使用或创建单例,或者程序创建或运行不太繁重,那么你可以使用“急切”地创建实例。

public class Singleton {
    //在程序开始的时创建
    private static Singleton uniqueInstance=new Singleton();;

    //私有化构造
    private Singleton(){}

    public static Singleton getInstance(){
        //返回
        return uniqueInstance;
    }
}

这个方法以来jvm加载类的时候创建静态变量,使用时确保是单例。

3.双重检查加锁,确保getInance()同步使用的次数

public class Singleton {
    //volatile确保多个线程正确处理
    private static volatile Singleton uniqueInstance;

    // 私有化构造
    private Singleton() {
    }

    public Singleton getInstance() {
        // 判断是否创建
        if (uniqueInstance == null) {

            synchronized (Singleton.class) {
                //双重判断
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        // 返回
        return uniqueInstance;
    }
}

这种方法可以对比第一种方法,增加了很多性能,应为除了第一个创建是同步外,后面的都不是同步的。但是注意volatile 关键字是java 1.5才出现的,所以1.4以及以前的不能使用volatile 。

所以当我们使用单例模式一定要小心加小心,根据自己程序的实际情况来选着哪一种实现方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值