zoukankan      html  css  js  c++  java
  • 04、Java模式 单例模式

    单例模式

    单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。

    单例模式有 3 个特点:

    单例类只有一个实例对象;

    该单例对象必须由单例类自行创建;

    单例类对外提供一个访问该单例的全局访问点

    单例模式的有点和缺点

    单例模式的优点:

    • 单例模式可以保证内存里只有一个实例,减少了内存的开销。
    • 可以避免对资源的多重占用。
    • 单例模式设置全局访问点,可以优化和共享资源的访问。

    单例模式的缺点:

    • 单例模式没有接口,扩展困难。如果要扩展,则除了修改原来的代码,没有第二种途径,违背开闭原则。
    • 在并发测试中,单例模式不利于代码调试。
    • 单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则。

    单例模式的结构如下图所示:

    单例模式实现

    Singleton 模式通常有两种实现形式:懒汉式和饿汉式。

    懒汉式单例

    该模式的特点是类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例。代码如下:

    public class LazySingleton {
        // //保证 instance 在所有线程中同步
        private static volatile LazySingleton instance;
        private LazySingleton(){
            // 在类中私有化构造函数,避免外部实例化
        }
        public static synchronized LazySingleton getInstance(){
            if (instance == null){
                instance = new LazySingleton();
            }
            return instance;
        }
    }
    

    注意:多线程情况下需要加volatile 和 synchronized关键字,否则导致线程安全问题。(同步会影响性能)

    饿汉式单例

    该模式的特点是类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。

    public class HungrySingleton  {
        private static final HungrySingleton instance = new HungrySingleton();
        private HungrySingleton(){}
        public static HungrySingleton getInstance(){
            return instance;
        }
    }
    

    注意:饿汉式在类创建时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的。

    多例模式

    单例模式可扩展为有限的多例(Multitcm)模式,这种模式可生成有限个实例并保存在 ArrayList 中,客户需要时可随机获取。

    当存在这样的类,只需要有限数量实例的情况下,可以使用多例 。

    代码示例如下:

    public class Multiton {
        private static List<Multiton> list = new ArrayList<>();
        private static final int MAX_VALUE = 10;
        static {
            for (int i = 0; i < MAX_VALUE; i++) {
                list.add(new Multiton(i));
            }
        }
        // 私有构造函数,避免外部创建
        private Multiton(int i){ }
    
        public static Multiton getRandomInstance(){
            int value = (int) (Math.random() * MAX_VALUE);
            return list.get(value);
        }
    }
    

    在main函数中的使用方法如下:

    public class Main {
        public static void main(String[] args) {
            Multiton randomInstance1 = Multiton.getRandomInstance();
            Multiton randomInstance2 = Multiton.getRandomInstance();
            // 产生十个实例,相等的可能性比较小
            boolean isEquals = randomInstance1 == randomInstance2 ? true : false;
            System.out.println(isEquals);
        }
    }
    

    注意:多例模式可以控制类的实例数量,提高效率,但是也提高了实例的维护复杂度。

  • 相关阅读:
    Git .gitignore文件简介及使用
    JMeter 报告监听器导入.jtl结果文件报错解决方案
    JMeter 中实现发送Java请求
    JMeter 正则表达式提取器结合ForEach控制器遍历提取变量值
    Tomcat_记一次tomcatwar包应用简单部署过程
    Python_基于Python同Linux进行交互式操作实现通过堡垒机访问目标机
    Python_关于多线程下变量赋值取值的一点研究
    JMeter 后置处理器之正则表达式提取器详解
    性能测试 CentOS下结合InfluxDB及Grafana图表实时展示JMeter相关性能数据
    Python 标准类库-数据类型之copy-深拷贝浅拷贝操作
  • 原文地址:https://www.cnblogs.com/pengjingya/p/14939712.html
Copyright © 2011-2022 走看看