Java的单例设计模式详解

  

<强> 1。什么是单例模式

  
      <李>生成一个独一无二的,保证任何时刻一个类只有一个实例的模式李   <李>确保一个类只有一个实例,并提供一个全局访问点李   <李>可以在需要时才创建对象,避免了全局变量在程序启动时就得创建对象的缺点。   
  

<强> 2。经典单例模式实现

        公开课MyInstance {//第一步:私有化构造器,只有类自身才能调用构造器外部类不能够直接新出这个类的实例对象   私人MyInstance () {}//第二步:声明一个全局静态变量来记录自身实例的对象,也是私有的,限制其它外部类访问   私有静态MyInstance MyInstance;//第三步:提供一个外部可访问的静态公开方法,来获得该类的唯一实例   公共静态MyInstance getMyInstance () {//第四步:进行判断自身类对象如果为空,则创建一个实例   如果(myInstance==null) {//这里的方法只执行了一次,生成了一个唯一的类对象   myInstance=new myInstance ();   }//第五步:如果不为空,则返回该类对象,故由始至终,该类对象只初始化过一次,只有一个对象存在,这就是单例模式   返回myInstance;   }   }      

<强> 3。经典模式存在的缺陷

  

这种经典模式也称之为懒汉式单例模式(懒instantiaze),因为它是延迟化实例化的,即如果我们不需要这个实例,则它永远不会被初始化,只有在调用过一次实例化方法后,才会被创建出对象。

  

在多线程的情况下可能会产生并发问题,因为获取单例的方法<代码> getMyInstance() 有可能被多个线程同时访问,这时就会有可能创建出两个以上的实例对象。这就要考虑要线程安全的问题了,解决问题就是在获取实例方法处加一个同步锁,这样就能轻松地解决线程并发的问题了。

        公共静态同步MyInstance getMyInstance () {//加同步锁关键字同步,这样在有线程访问这个方法时,其它线程只能等待当前线程访问结束才能访问这个方法。   如果(myInstance==null) {//这里的方法只执行了一次,生成了一个唯一的类对象   myInstance=new myInstance ();   }      

<>强4。多线程下同步所造成的性能问题

  

如果将获取实例的方法进行同步的话,会造成程序执行的效率大大地下降,而且单例对象生成只要调用一次方法即可,之后每次调用这个方法时,同步都是一种累缀,有可能会拖垮程序的性能。

  

当然如果你的程序对于性能的要求并不是很高的话,用同步的方法获取单例是最简单而有效的。

  

为保证程序的性能并且又不会出现并发的问题,可以使用另一种生成单例对象的模式,叫做饿汉式单例模式(热切instantiaze)

        公开课MyInstance {//第一步:私有化构造器   私人MyInstance () {}//第二步:声明一个全局静态变量来记录自身实例的对象,并进行实例化   私有静态MyInstance MyInstance=new MyInstance ();//第三步:提供一个外部可访问的静态公开方法,来获得该类的唯一实例   公共静态MyInstance getMyInstance () {   返回myInstance;   }      

这个模式使JVM在加载这个类时会马上创建唯一的单例对象,这样就能保证任何线程访问静态单例变量myInstance时,单例对象一定被实例化过了。

  

<强> 5。利用双重检查加锁来提升性能

  
      <李>首先检查实例是否已经创建了,如果没有才进行同步获取实例的方法,这样就保证了实例方法只会在第一次获取实例时会同步。   <李>这里要用到一个关键字不稳定,此关键字确保了当实例变量myInstance被初始化成实例对象时,多个线程能正确地处理实例变量。注意,这个关键字只有在Java1.5及以上的版本才会对双重检查加载生效。   
        公开课MyInstance {//用关键字挥发性修饰实例变量   私人不稳定的静态MyInstance MyInstance;//私有化构造器   私人MyInstance () {}   公共静态MyInstance getMyInstance () {//第一次检查实例是否存在   如果(myInstance==null) {//如果不存在则进入同步区块   同步(MyInstance.class) {   如果(myInstance==null) {//第二次检查,如果不为空才真正创建实例对象   myInstance=new myInstance ();   }   }   }//如果不为空,则直接返回该类对象   返回myInstance;   }   }      

Java的单例设计模式详解