创建型模式之 -- 单例模式

1.懒汉模式

1.构建单例对象

ps:为了测试再一次创建的Singleton对象是否是同一对象,为其添加属性name

public class Singleton {
    //添加属性name
    private String name;
    private static Singleton instance;
    //私有的构造方法,使其不能通过new得到该对象
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {//判断是否为空,实现单例
            instance = new Singleton();
        }
        return instance;
    }
    //get和set方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Singleton [name=" + name + "]";
    }
}

 

2.测试

public class HungryModeTest {
    @Test
    public void hungryMode(){
        //通过其方法创建singleton对象
        Singleton singleton = Singleton.getInstance();
        //为name属性赋值
        singleton.setName("张三");
        System.err.println(singleton.toString());
        //创建新的singleton对象singletonNew
        Singleton singletonNew= Singleton.getInstance();
        System.err.println(singletonNew.toString());
    }
}

3.测试输出结果

4.总结:

  懒汉式当需要的时候才会创建对象,但是当多个线程同时加载时,懒汉就会出现同时构造了多个对象的问题,懒汉式是线程不安全的.

 2.线程安全的懒汉模式

1.为普通懒汉试添加线程锁

ps:添加红色部分为线程锁,解决多线程的问题

public class Singleton {
    //添加属性name
    private String name;
    private static Singleton instance;
    //私有的构造方法,使其不能通过new得到该对象
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (instance == null) {//判断是否为空,实现单例
            instance = new Singleton();
        }
        return instance;
    }
    //get和set方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Singleton [name=" + name + "]";
    }
}

 

 3.饿汉式

1.创建单例对象

public class Singleton {
    // 添加属性name
    private String name;
    private static Singleton instance = new Singleton();
    //私有的构造方法
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
    // get和set方法
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public String toString() {return "Singleton [name=" + name + "]";}
}

2.测试

ps:测试代码与上面懒汉测试代码相同

3.测试结果

 

4.双重校验锁

1.加锁的懒汉模会出现延迟加载,而双重校验锁是更进一步的改进

public class Singleton {
    // 添加属性name
    private String name;
    //通过volatile禁止指令重排序优化,保证对象初始化
    private static volatile Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {//为空判断保证单例
            synchronized (Singleton.class) {//线程锁
                if (instance == null) {//在一次为空判断,保证多线程
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
    // get和set方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString() {
        return "Singleton [name=" + name + "]";
    }
}

 

5.静态内部类

1.利用类加载机制来保证只创建一个实例

public class Singleton {
    // 添加属性name
    private String name;
    private static class SingletonInner{ //内部类 
        public static Singleton instance = new Singleton();  
    }  
    private Singleton(){}  //私有构造
    public static Singleton newInstance(){  
        return SingletonInner.instance;  
    }  
    // get和set方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString() {
        return "Singleton [name=" + name + "]";
    }
}

 

 

欢迎转载:

中文名:惠凡

博客名:淹死的鱼o0

转载时请说明出处:http://www.cnblogs.com/huifan/

posted @ 2018-01-25 18:21  淹死的鱼o0  阅读(166)  评论(0编辑  收藏  举报