zoukankan      html  css  js  c++  java
  • java设计模式-单例模式

    单例模式

    定义

    确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。

    实现步骤

    (1)     定义静态私有成员变量

    (2)     创建唯一实例(多种实现方式)

    (3)     定义私有构造函数,确保外部不能使用new关键字创建对象

    (4)     提供外部获取单例对象的静态方法

    实现方式

    饿汉式单例类

    饿汉式单例类是最简单的单例类,定义的静态私有成员变量在类加载的时候就会创建单例对象。饿汉式单例是线程安全的,不会出现创建多个单例对象的情况。

    代码实现
    /**
     * 饿汉式单例类
     * @create 2018-04-12 17:05
     **/
    public class EagerSingleton {
    
        //定义静态私有成员变量,创建单例对象
        private static EagerSingleton instance = new EagerSingleton();
    
        //定义私有构造函数,确保外部不能使用new关键字创建EagerSingleton实例对象
        private EagerSingleton() {
    
        }
    
        //提供外部获取单例对象的静态方法
        public static EagerSingleton getInstance() {
            return instance;
        }
    }
    优缺点

    优点:线程安全,在多线程下不会出现创建多个实例对象的情况。

    缺点:未实现懒加载,类加载时即初始化单例对象,加载时间可能较长。

    懒汉式单例类

    懒汉式单例也是一种实现单例的经典方式,单例对象不是在类加载时创建,而是在第一次调用getInstance方法时创建,实现了懒加载,但是在多线程下会出现创建多个单例对象的情况。

    非线程安全代码实现
    /**
     * 非线程安全懒汉式单例类
     * @create 2018-04-12 22:14
     **/
    public class LazySingleton {
        //定义静态私有成员变量
        private static LazySingleton instance = null;
    
        //定义私有构造函数,确保外部不能使用new关键字创建EagerSingleton实例对象
        private LazySingleton() {
    
        }
    
        //提供外部获取单例对象的静态方法
        public static LazySingleton getInstance() {
            if (null == instance) {
                //创建单例对象
                instance = new LazySingleton();
            }
            return instance;
        }
    }
    优缺点

    优点:实现懒加载

    缺点:非线程安全,在多线程下不能正常工作

    线程安全代码实现
    /**
     * 线程安全懒汉式单例类
     * @create 2018-04-12 22:14
     **/
    public class LazySingleton {
        //定义静态私有成员变量
        private static LazySingleton instance = null;
    
        //定义私有构造函数,确保外部不能使用new关键字创建EagerSingleton实例对象
        private LazySingleton() {
    
        }
    
        //创建实例对象时,加上线程锁,实现线程安全
        public static synchronized LazySingleton getInstance() {
            if (null == instance) {
                //创建单例对象
                instance = new LazySingleton();
            }
            return instance;
        }
    }
    优缺点

    优点:实现懒加载、线程安全。

    缺点:由于给getInstance方法加了线程锁,每次调用该方法时,都会被锁住,在多线程环境下,运行效率很低。

    可以给上面这种方式进行优化,线程锁加载创建单例对象的地方,而不直接加在getInstance方法上。

    优化后的代码:

    package com.lnjecit.singleton;
    
    /**
     * 线程安全懒汉式单例类
     *
     * @create 2018-04-12 22:14
     **/
    public class LazySingleton {
        //定义静态私有成员变量
        private static LazySingleton instance = null;
    
        //定义私有构造函数,确保外部不能使用new关键字创建EagerSingleton实例对象
        private LazySingleton() {
    
        }
    
        //创建实例对象时,加上线程锁,实现线程安全
        public static LazySingleton getInstance() {
            if (null == instance) {
                synchronized (LazySingleton.class) {
                    //创建单例对象
                    instance = new LazySingleton();
                }
            }
            return instance;
        }
    }

    这种方式可以在一点程度上提高运行效率,但是还是在多线程情况下,还是有可能出现创建多个单例,当instance为null时,多个线程同时访问getInstance方法,由于instance为null,所以都会创建instance对象,

    造成出现多个实例。

    双重锁定
    代码实现
    /**
     * 双重校验锁定单例类
     * @create 2018-04-12 22:14
     **/
    public class LazySingleton {
        /**
         *定义静态私有成员变量,
         *使用volatile关键字修饰,确保线程可见性,当一个线程修改了instance对象,其它线程也能看到修改后的值
         */
        private volatile static LazySingleton instance = null;
    
        //定义私有构造函数,确保外部不能使用new关键字创建EagerSingleton实例对象
        private LazySingleton() {
    
        }
    
        //创建实例对象时,加上线程锁,实现线程安全
        public static LazySingleton getInstance() {
            if (null == instance) {
                synchronized (LazySingleton.class) {
                    if (null == instance) {
                        //创建单例对象
                        instance = new LazySingleton();
                    }
                }
            }
            return instance;
        }
    }
    优缺点

    优点:实现懒加载、线程安全。

    缺点:volitile关键字会屏蔽JVM对代码的优化,存在导致运行效率低的可能。 

    内部静态类

    饿汉式单例类不能实现懒加载,懒汉式需要加锁、判断等方式确保线程安全,实现过程繁琐。而在单例内中增加一个内部静态类可减少加锁和判断的过程,就可实现懒加载和线程安全,并且不影响运行效率。

    实现代码
    /**
     * 静态内部类
     * @create 2018-04-12 17:05
     **/
    public class Singleton {
    
        //定义私有构造函数,确保外部不能使用new关键字创建EagerSingleton实例对象
        private Singleton() {
    
        }
    
        private static class SingletonHolder {
            //创建单例对象
            private static final Singleton INSTANCE = new Singleton();
        }
    
        //提供外部获取单例对象的静态方法
        public static Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }
    优缺点

     优点:懒加载、线程安全。

     缺点: 

    应用场景

    请参考:

    https://blog.csdn.net/lovelion/article/details/7420889

    https://blog.csdn.net/tanyujing/article/details/14160941

    参考资料

    1、https://blog.csdn.net/lovelion/article/details/7420886

  • 相关阅读:
    .NET中TreeView控件从数据库获取数据源
    .NET中GridView控件的全选删除
    TreeView无限极分类绑定(从数据库读取数据源)
    .NET中GridView代码更改列名
    .NET读写cookie方法
    .NET中GridView控件的高亮显示和删除前弹框提示
    Repeater控件的多层嵌套,DataList控件的多层嵌套
    .NET一些常用的语句集合(不断更新中)
    解决IE5、IE6、IE7与W3C标准的冲突,使用(IE7.js IE8.js)兼容
    kindeditor富文本编辑器ASP.NET源码下载
  • 原文地址:https://www.cnblogs.com/zuidongfeng/p/8807750.html
Copyright © 2011-2022 走看看