Java中的单例模式

来源:互联网 发布:在淘宝买手机可靠吗 编辑:程序博客网 时间:2024/06/03 22:05

Java中的单例模式

  • 什么叫做单例模式
    • 在Java中,一个类有且只有一个对象,并且自行实例化对象供系统使用。
  • 保证只有一个对象

    • 将类的构造方法私有化,这样外界不能直接得到类的实例对象

      public class Single{    private Single(){}    private static Single sIntance = new Single();    public static Single getInstance(){        return sInstance;    }}

恶汉式

类加载的时候对象就已经存在,饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,上述例子就是一个恶汉式

懒汉式

类加载的时候对象还不存在,就是所谓的延迟加载方式,需要时再进行创建,懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的

public class Single {    private static Single sIntance = null;    private Single() {}    // 这种情况是线程不安全的    public static Single getInstance() {        if (sIntance == null) {            sIntance = new Single();        }        return sIntance;    }}   

线程安全

public class Single {    private static Single sIntance = null;    private Single() {}    public static Single getInstance() {        if (sIntance == null) {            synchronized(Single.class){                sIntance = new Single();            }        }        return sIntance;    }}   

看似完美,但是指令重排序会引起空指针异常
原因来自sInstance = new Single();这里可以分解为

memory = allocate();    //分配内存空间ctorInstance(memory);   //实例化对象sIntance = memory;      //sIntance 指向分配的内存地址

但是重排序后

memory = allocate(); //分配内存空间sIntance = memory;   //sIntance 指向分配的内存地址ctorInstance(memory);//实例化对象

在jdk1.5之后使用volatile关键字禁止重排序

public class Single {    private static volatile Single sIntance = null;    private Single() {}    public static Single getInstance() {        if (sIntance == null) {            synchronized(Single.class){                sIntance = new Single();            }        }        return sIntance;    }}   

使用内部类的方式实现单例模式

    public class Single {        public static class SingleHolder{            public static Single sIntance = new Single();        }        private Single() {}        public static Single getInstance() {            return SingleHoler.sIntance;        }    }   

使用内部类的方式,既能保证线程安全,有能保证在调用方法的是加载这个内部类,创建的对象是随着内部类的加载而加载的。