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

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

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

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

          单例模式

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

            单例模式类图结构:

                               

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

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; 		       } }     
              此方法保证了对象在生命周期内只能被锁定一次,因而不会影响性能!推荐