java中的单例模式

目录

第一.饿汉式

第二.懒汉式

第三.静态内部类 推荐

总结


程序开发中有时候某些对象我们只需要一个,如:线程池、缓存、对话框等等,对于这类对象我们只能有一个实例,如果我们制造出多个实例,就会导致很多问题产生。但是我们怎样才能保证一个类只有一个实例并且能够便于访问?这里我们想到了全局变量,全局变量确实是可以保证该类可以随时访问,但是它很难解决只有一个实例问题。最好的办法就是让该自身来负责保存它的唯一实例。通过上面简单介绍,我们可以对单例模式有一个简单的认识。所谓单例模式就是确保某一个类只有一个实例,并且提供一个全局访问点。从上面可以看出单例模式有如下几个特点:1.它只有一个实例;2.它必须要自行实例化; 3.它必须自行向整个系统提供访问点。

单例的创建模式有很多种,下面的文章中我只介绍三种方式,多余的就不说了!

第一.饿汉式

/**
 * 饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题
 * @author Administrator
 *
 */
public class Single1 {
    private static  final Single1 single1=new Single1();

    private Single1() {
    }
    //静态工厂方法
    public   static  Single1 getInstance(){
        return single1;
    }
}

第二.懒汉式

  懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的下面的getInstance2和getInstance3,在资源加载和性能方面有些区别。

/**
 * 懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的下面的getInstance2和getInstance3,在资源加载和性能方面有些区别。
 * 还有一种方法是静态内部类,也是线程安全的
 */
public class Single2 {
    private  static  Single2 single2=null;

    Single2() {
    }

    /**
     * 线程不安全
     * @return
     */
    public  static Single2 getInstance(){
        if(single2==null){
             single2=new Single2();
        }
        return single2;
    }

    /**
     * 在getInstance方法上加同步(性能较差)
     * @return
     */
    public  static synchronized  Single2 getInstance2(){
        if(single2==null){
            single2=new Single2();
        }
        return single2;
    }

    /**
     * 双重检查锁定(DCL 双检查锁机制)推荐
     * @return
     */
    public   static Single2 getInstance3(){
        if(single2==null){
            synchronized (Single2.class){
                if(single2==null){
                    single2=new Single2();
                }
            }
        }
        return single2;
    }
}

第三.静态内部类 推荐

利用静态内部类在原始类初始化的时候不加载的特性(只有在调用的时候才会加载),可以实现单例模式。

/**
 * 静态内部类 推荐
 */
public class Single3 {
    private static Logger logger= LoggerFactory.getLogger(Single3.class);
    private  static  class CrateSingle{
        private static final  Single3 single3=new Single3();
    }

    private  Single3() {
       
    }

    public   static  final Single3  getInstance(){
        return  CrateSingle.single3;
    }
}

总结

优点              
一、节约了系统资源。由于系统中只存在一个实例对象,对与一些需要频繁创建和销毁对象的系统而言,单例模式无疑节约了系统资源和提高了系统的性能。             
二、因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。         

缺点             
一、由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。             
二、单例类的职责过重,在一定程度上违背了“单一职责原则”。(因为单例设计模式,在代码getInstance书写的过程中,有些代码是比较复杂的,而且会伴有一些初始化的函数,会造成该类的多种初始化或者组装代码的书写。)

下列几种情况可以使用单例模式。              
一、系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。             
二、客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值