设计模式---单例设计模式(Singleton Pattern)

           在学习单例模式之前,首先我们必须明白为何需要单例模式。即单例模式存在的意义。考虑到

    这样一种场景:在整个应用中某个类只有一个独一无二的实例,也就是"单例",例如笔者在以前完

    成的一个聊天程序的聊天窗口。有这样一种需求,即是当聊天窗口已经打开的时候不在实例化它。

          基于上述描述,单例模式的存在是有其实际意义的!那么,何为单例模式呢?

          单例模式

                       单例模式指的是一个类仅有一个实例对象,并且提供对这个对象的一个全局访问点。

            单例模式类图结构:

                               

                  具体来说单例模式是如何实现的呢?下面是代码:

package com.kiritor;
/**
 * @author Kiritor
 * 懒汉式单例模式*/
public class Singleton {
   private static final Singleton singleton = null;
   //私有构造方法
   private Singleton()
   {
       
   }
   public static Singleton getInstance()
   {
       if(singleton==null)
       {
           singleton = new Singleton();
       }
       return singleton;
           
   }
}
                 由上述代码可以看出 Singleton类通过将构造方法限定为私有的(private),避免了类在外部

      被实例化。Singleton的唯一实例只能通过getInstance方法得到。

                 Tips:实际上,通过反射机制是可以得到该实例对象的,不过这里姑且不论!而且上述实’

      现在多线程的情况下也是不成立的。

                  观察上述代码可知,Singleton类中拥有一个Singleton类型的静态常量,由该成员的初始化

      方式的不同,单例模式大体上可以分为两种。

                 1、懒汉式单例模式:

                            把对象的创建放在方法中去,延迟了创建(懒得)。也就是上述代码的实现。

                 2、饿汉式单例模式:

                           在声明对象的时候初始化(急不可耐),实现代码如下。

      

package com.kiritor;
/**
 * @author Kiritor
 * 饿汉式单例模式*/
public class Singleton {
   private static Singleton singleton = new Singleton();
   //私有构造方法
   private Singleton()
   {
	   
   }
   public static Singleton getInstance()
   {
	  
	   return singleton;
		   
   }
}
                   那么,他们两者具体又有什么不同呢?

                    懒汉式模式,只有外部对象第一次请求实例的时候才会去创建实例,运行时获得对象的速度较慢

             但是,加载类的时候速度较快,在其整个的周期中只有一部分时间占用资源。饿汉式模式正好与其

             相反。

                   前面提到,上述单例模式并不是线程安全的,没有考虑到多线程的情况,解决方法如下:

                      1、 (使用锁机制:就是线程对临界区的访问权限)

package com.kiritor;
/**
 * @author Kiritor
 * 懒汉式单例模式*/
public class Singleton {
   private static Singleton singleton = null;
   private static Object object = new Object();
   //私有构造方法
   private Singleton()
   {
	   
   }
   public static Singleton getInstance()
   {
         /**这里事先并不知道singeton是否被创建,因此不对方法进行锁*/
          synchronized(object)
	   {
		   if(singleton== null)
			  {
				  singleton = new Singleton();
			  }
	   }
	 
	   return singleton;
		   
   }
}
                上述代码还可以进一步优化:

                   2、使用双重锁

       

package com.kiritor;
/**
 * @author Kiritor
 * 饿汉式单例模式*/
public class Singleton {
   private static Singleton singleton = null;
   private static Object object = new Object();
   //私有构造方法
   private Singleton()
   {
	   
   }
   public static Singleton getInstance()
   {
	   if(singleton== null)
	   {
	   synchronized(object)
	   {
		   /*这里在做一次的判断是:
		    * 当两个线程同时运行到singleton=null时
		    * 只能有一个A线程运行,另一个B不能运行
		    * 但是当不做这层判断的时候,A执行完成后(有了一个实例a),
		    * B开始执行,由于没有singeton==null的判断B结束之后有了一个实例b
		    * 这样就不能保证单例了*/
		   if(singleton== null)
			  {
				  singleton = new Singleton();
			  }
	   }
	  
	   }
	   return singleton;
		   
   }
}
    
              此方法保证了对象在生命周期内只能被锁定一次,因而不会影响性能!推荐

                 

                  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值