1.单例模式

一  最简单的实现方法

定义一个私有的构造函数,保证对象不能为外部实例化,同时返回一个静态对象实例。

public class SinglertonClass{

            public static final SingletonClass getInstance = new SingletonClass();

            private  SinglertonClass(){

            }

}

上述方法缺点是无论这个对象是否被使用,都会默认创建一个对象,如果对象很重造成资源浪费。

二  lazy—loaded(延时加载,需要用的时候才去初始化)

public class SingletonClass{

           private static SingletonClass instance = null;

           public static SingletonClass getInstance(){

                      if(instance == null){

                             instance = new SingletonClass();

                        }

                     return  instance;

             }

            private SingletonClass(){

            }

}

这段代码在单线程的时候有效,但在多线程场景下,并不能保证只有一个实例。

当多个线程同时发现对象为null时,都会各自去new一个对象。

三 加锁(double-checked locking)

public class SingletonClass{

private static SingletonClass instance = null;

public static SingletonClass getInstance(){

          if(instance == null){

                   synchronized(SingletonClass.class){

                         if(instance ==  null){

                                instance = new SingletonClass();

                           }

                    }

            }

           return  instance;

     }

      private SingletonClass(){

      }

四  静态内部类

public class SingletonClass {

           private static class SingletonClassInstance{

                       private static final SingletonClass instance = new SingletonClass(); 

           }

 

          public static SingletonClass getInstance(){

                     return  SingletonClassInstance.instance;

         }

 

        private SingletonClass(){

 

        }

}

上述单例模式实现代码中,使用了Java的静态内部类。在这段代码中,因为SingletonClass没有static的属性,因此并不会被初始化。直到调用getInstance()的时候,会首先加载SingletonClassInstance类,这个类有一个static的SingletonClass实例,因此需要调用SingletonClass的构造方法,然后getInstance()将把这个内部类的instance返回给使用者。由于这个instance是static的,因此并不会构造多次。

由于SingletonClassInstance是私有静态内部类,所以不会被其他类知道,同样,static语义也要求不会有多个实例存在。并且,JSL规范定义,类的构造必须是原子性的,非并发的,因此不需要加同步块。同样,由于这个构造是并发的,所以getInstance()也并不需要加同步。并且Effiective Java也推荐的这种方式。

注意:懒汉模式在运行的时候获取对象比较慢(因为类加载是并没有创建对象实例),但是加载类的时候比较快(因为此时不创建对象实例),饿汉模式是在运行的时候获取对象较快(因为在加载类是就创建了对象实例),加载类的时候慢(此时还需要创建对象实例)。

posted @ 2017-10-09 21:20  小蚕豆  阅读(91)  评论(0)    收藏  举报