Java设计模式--单例类

来源:互联网 发布:传奇世界数据库 编辑:程序博客网 时间:2024/06/05 14:14

Singleton

饿汉模式

    public class Sigleton {    //饿汉模式 outInstance是私有的    private static Sigleton ourInstance = new Sigleton();    /**     * 此实现是线程安全的  JVM在加载此类时,因为对于static属性的初始化只能由一个线程执行且仅执行一次     * 缺点:instance在类装载时就实例化 这时候初始化instance显然没有达到lazy loading的效果     * @return     */    public static Sigleton getInstance() {        return ourInstance;    }    //把构造函数声明为private 客户对象无法创建该实例    private Sigleton() {    }}

懒汉模式

public class Sigleton2 {    //懒汉模式(需要时才实例化对象)    private static Sigleton2 instance;    /**     * 线程不安全 原因:getInstance在高并发环境下可能会被同时调用,导致if(instance==null)判断就不靠谱     * @return     *///    public static Sigleton2 getInstance() {//        if (instance == null) {//            instance = new Sigleton2();//        }//        return instance;//    }    /**     * 解决方法:添加synchornized关键字     * 缺点:性能降低     * @return     */    public static synchronized Sigleton2 getInstance() {        if (instance == null) {            instance = new Sigleton2();        }        return instance;    }    private Sigleton2(){    }}

双重校验锁

public class DoubleCheckSingleton {    //此方法需要在Java 5及以上的版本才能运行  volatile关键字在Java5引入    public volatile static DoubleCheckSingleton instance = null;    private DoubleCheckSingleton(){}    public static DoubleCheckSingleton getInstance() {        if (instance == null) { //检查实例是否创建 如果没有把    DoubleCheckSingleton.class设置为同步            synchronized (DoubleCheckSingleton.class) {                if (instance == null) {  //double check                    instance = new DoubleCheckSingleton();                }            }        }        return instance;    }}

静态内部类

public class StaticSingleton {     private static class SingletonHolder {         private static final StaticSingleton INSTANCE = new StaticSingleton();     }    private StaticSingleton (){}    //这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程    public static final StaticSingleton getInstance() {            return SingletonHolder.INSTANCE;    }}

Singleton的序列化

如果单例类实现了Serializable接口,默认情况下,每次反序列化总会创建一个新的实例对象。
解决方法:重写readResolve()方法,直接返回单例对象

package Sigleton;import java.io.Serializable;/** * Created by Zz on 2017/5/3 0003. */public class Sigleton implements Serializable{    private static final long serialVersionUid = -6012841243252L;    //饿汉模式 outInstance是私有的    private static Sigleton ourInstance = new Sigleton();    /**     * 此实现是线程安全的  JVM在加载此类时,因为对于static属性的初始化只能由一个线程执行且仅执行一次     * 缺点:instance在类装载时就实例化 这时候初始化instance显然没有达到lazy loading的效果     * @return     */    public static Sigleton getInstance() {        return ourInstance;    }    //把构造函数声明为private 客户对象无法创建该实例    private Sigleton() {    }    private Object readResolve(){        return ourInstance;    }}
0 0
原创粉丝点击