栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

①单例模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

①单例模式

返回设计模式目录

单例模式
  • 概念
  • 代码
    • 1、一般创建流程
    • 2、几种实现方式
      • ①饿汉式
      • ②懒汉式(线程不安全)
      • ③懒汉式(线程安全)
      • ④双检锁
      • ⑤登记式(静态内部类)
      • ⑥枚举(推荐)
  • 总结

概念

采用单例模式设计的类负责创建自己的对象,并且确保只有单个对象被创建。该类需要提供一种访问其唯一对象的方式,并且可以直接访问,不需要实例化该类的对象。

代码 1、一般创建流程

用单例模式设计一个类

public class SingleObject {
    // 1、隐藏构造函数,禁止在其他代码中实例化该类
    private SingleObject() {
    }

    // 2、创建该类的唯一对象
    private static SingleObject instance = new SingleObject();

    // 3、对外提供访问该类的唯一对象的方式
    public static SingleObject getInstance() {
        return instance;
    }

    // 4、其他代码
    // …………
}

使用该类的唯一对象

public class Main {
    public static void main(String[] args) {
        // 1、获取唯一对象
        SingleObject singleObject = SingleObject.getInstance();
        
        // 2、调用对象的某些方法或属性
        // singleObject.xxx()
    }
}
2、几种实现方式
实现方式Lazy初始化线程安全
饿汉式
懒汉式
懒汉式(线程安全)
双检锁
登记式
枚举
①饿汉式
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

饿汉式基于Java类加载机制,在加载类的时候就实例化该类,避免了多线程同步问题。但是使用这种方式容易创建垃圾对象,浪费内存。

②懒汉式(线程不安全)
public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

懒汉式实现方式在第一次使用该类的对象时才进行实例化,避免创建多余的对象。但是这种实现方式无法保证线程安全,在多线程环境下有可能多次进行实例化造成程序异常。

③懒汉式(线程安全)
public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

对懒汉式的getInstance()方法加synchronized锁即可保证线程安全,但是这种实现方式会影响程序的执行效率,适用于getInstance()方法调用不太频繁的场景。

④双检锁
public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

双检锁方式针对线程安全的懒汉式做了进一步的改进——只对getInstance()方法中的实例化部分代码加锁。即只在修改该类的信息的时候保证线程安全,调用该类的实例时则无需如此。这样既保证只创建一次对象,也能有较好的性能。

⑤登记式(静态内部类)
public class Singleton {
    private static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }

    private Singleton() {
    }

    public static final Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

登记式同样利用了Java的类加载机制,不同于饿汉式,登记式利用静态内部类来确保该类只实例化一次。在外部类被加载时,静态内部类不会立刻被加载,因此外部类不会立刻被实例化。直到第一次调用getInstance()方法时,才会实例化外部类。

⑥枚举(推荐)
public enum Singleton {
    INSTANCE;

    public void doSomething() {

    }
}

使用枚举是实现单例最简单的方式。使用这种方法不仅可以避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。

总结

单例模式的使用场景:
某个类需要被全局使用,为了避免对象的频繁创建与销毁,可以采用单例的设计模式(比如数据库连接、I/O等)

单例模式的编码思路和习惯:
(不使用枚举)隐藏构造函数→(根据Lazy初始化和多线程同步需求修改)→private实例化→public方法提供类的对象→其他代码
(使用枚举)添加唯一的实例属性INSTANCE→其他代码

返回设计模式目录

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/666921.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号