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


    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/

  • 相关阅读:
    PHP 上传文件限制
    vim设置golang语法高亮 (Centos)
    linux下安装配置go语言环境
    Vim升华之树形目录插件NERDTree安装图解(ubuntu)
    linux下配置Node.js环境
    RabbitMQ的使用(二)- RabbitMQ服务在单机中做集群
    RabbitMQ的使用(一)- RabbitMQ服务安装
    Exceptionless(二)
    Exceptionless
    SQL Server2012如何打开2016的profiler文件
  • 原文地址:https://www.cnblogs.com/huifan/p/8352610.html
Copyright © 2020-2023  润新知