标签搜索

目 录CONTENT

文章目录

Java-设计模式(单例模式)

WP&CZH
2022-12-20 / 0 评论 / 0 点赞 / 381 阅读 / 1,239 字 / 正在检测是否收录...

单例模式

package top.tobing.test;

/**
 * @ClassName 饿汉式
 * @Description TODO
 * @Author wuning
 * @Date 2022/12/20 9:37
 * @Version 1.0
 */
public class Test {
    private static Test test=new Test();
    //构造方法私有,确保外界不能直接实例化
    private Test(){
    }
    //通过公有的静态方法获取对象实例
    private static Test getTest(){
        return test;
    }
}





package top.tobing.test;

/**
 * @ClassName 懒汉式
 * @Description TODO
 * @Author wuning
 * @Date 2022/12/20 9:39
 * @Version 1.0
 */
//懒汉式单例模式
public class Test01 {
    private static Test01 test01=null;
     //构造方法私有,确保外界不能直接实例化
    private Test01(){}
    //可以使用synchronized关键字对静态方法 getInstance()进行同步,线程安全的的懒汉式单例模式代码
    private synchronized Test01 getTest01(){
        if (test01==null){
            test01=new Test01();
        }
        return test01;
    }
}


//双重检查锁定(推荐使用)
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;
    }
}




解释双重检查锁定的代码:

声明volatile关键字:在双重检查锁定中,instance变量被声明为volatile,这样可以保证在多线程环境下对instance变量的可见性。当一个线程修改instance的值时,其他线程能够立即看到最新的值,避免了线程之间的数据不一致性。

第一次检查(if (instance == null)):在getInstance()方法中,首先检查instance是否为null,如果为null,才进入同步块进行实例的创建。这样可以避免不必要的同步操作,如果instance已经被初始化,后续线程直接返回已经存在的实例。

同步块:如果instance为null,线程进入同步块(synchronized (Singleton.class)),此时只有一个线程能够进入同步块,其他线程必须等待。

第二次检查(if (instance == null)):在同步块内部,再次检查instance是否为null,这是为了防止多线程环境下重复创建实例。因为在第一次检查之后,可能有其他线程已经进入同步块并创建了实例。

创建实例:如果第二次检查也确认instance为null,就在同步块内部创建实例。

双重检查锁定可以在多线程环境下保证单例模式的线程安全性,并且通过减少同步的范围来提高性能。但要注意,双重检查锁定只适用于Java 5及以上版本,因为在Java 5之前的JVM对volatile关键字的实现存在一些问题,可能会导致双重检查锁定失效。

单例模式是一种常用的设计模式,其优点和特点包括:

优点:

确保只有一个实例:单例模式确保在整个应用程序中只有一个实例存在,避免了多个实例的创建,节省了系统资源。
全局访问点:由于只有一个实例存在,并提供了一个全局访问点,可以方便地访问该实例,避免了对实例的重复创建和传递。
适用于资源共享:当有多个对象需要共享某一资源时,使用单例模式可以确保只有一个实例访问该资源,避免了资源的浪费和冲突。
避免全局变量:单例模式提供了一个全局访问点,可以取代全局变量的作用,使代码更加模块化和可维护。

特点:

私有构造方法:单例模式的类通常会将构造方法设为私有,以防止外部直接实例化该类。
静态实例:单例模式一般会在类内部创建一个私有的静态实例,并提供一个静态的获取实例的方法。
延迟初始化:懒汉式单例模式在第一次访问时才进行初始化,避免了不必要的资源消耗。而饿汉式单例模式则在类加载时就进行初始化,保证了线程安全,但可能影响应用启动速度。
需要注意的是,单例模式虽然具有很多优点,但也有其缺点。在某些场景下,单例模式可能会导致类的职责过于集中,违背了单一职责原则。另外,由于全局可访问的特性,滥用单例模式可能导致代码可维护性下降和单元测试困难。因此,在使用单例模式时,需要谨慎考虑,确保其在设计上是合理且必要的。

0

评论区