117.info
人生若只如初见

java单例模式的实现方法是什么

Java单例模式的实现方法有以下几种:

  1. 懒汉式(Lazy Initialization): 在第一次使用时才创建实例。线程不安全版本的懒汉式实现如下:
public class Singleton {
    private static Singleton instance;

    private Singleton(){}

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

可以通过在getInstance()方法上加锁synchronized来实现线程安全的懒汉式单例模式,但是会影响效率:

public class Singleton {
    private static Singleton instance;

    private Singleton(){}

    public static synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}
  1. 饿汉式(Eager Initialization): 在类加载时就创建实例,线程安全。实现如下:
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton(){}

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

由于在类加载时就创建实例,因此无法实现延迟加载。

  1. 双重检查锁定(Double Checked Locking): 在懒汉式的基础上,进行双重检查,确保线程安全且效率较高:
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变量可以保证多线程环境下的可见性和有序性。

  1. 静态内部类(Static Inner Class): 利用类的静态内部类来实现懒汉式的延迟加载和线程安全:
public class Singleton {
    private Singleton(){}

    private static class SingletonHolder{
        private static final Singleton INSTANCE = new Singleton();
    }

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

静态内部类只有在第一次使用时才会被加载,从而实现了延迟加载。

  1. 枚举(Enum): 使用枚举类来实现单例模式,可以保证线程安全和防止反射攻击:
public enum Singleton {
    INSTANCE;

    public void doSomething(){
        // do something
    }
}

未经允许不得转载 » 本文链接:https://www.117.info/ask/fee00AzsLAQFVBlY.html

推荐文章

  • Java中出现StackOverFlowError怎么解决

    当在Java中遇到StackOverflowError时,通常是由于递归调用的无限循环导致的。要解决此错误,可以采取以下一些措施: 检查递归方法的条件:确保递归方法的终止条件...

  • Java中serialVersionUID指的是什么意思

    在Java语言中,serialVersionUID是一个用于标识序列化类版本的静态变量。当一个类被序列化时,其serialVersionUID的值将与序列化数据一起存储。当反序列化时,系...

  • Java中的Replace和ReplaceAll有什么区别

    Java中的Replace和ReplaceAll都是用来替换字符串中的某些部分,但它们之间有一些区别。 Replace只能接受字符串作为参数,而ReplaceAll可以接受正则表达式作为参数...

  • Java的绘图库JFreeChart怎么使用

    要使用JFreeChart绘图库,您需要按照以下步骤操作: 下载JFreeChart库:您可以从JFreeChart的官方网站(https://www.jfree.org/jfreechart/)下载JFreeChart库。...

  • python中cv2.rectangle的功能有哪些

    cv2.rectangle函数在python中的功能如下: 绘制矩形:使用cv2.rectangle函数可以绘制一个矩形,通过指定矩形的左上角和右下角坐标,可以确定矩形的位置和大小。<...

  • K8s中crashloopbackoff问题怎么排查

    在Kubernetes中,CrashLoopBackOff问题通常是由于容器在启动后立即崩溃并重启多次引起的。要排查这个问题,可以按照以下步骤进行: 查看Pod的描述信息:运行kube...

  • 使用webapi要注意哪些事项

    使用Web API时,需要注意以下几个事项: 授权和身份验证:确保只有经过身份验证和授权的用户才能访问API。可以使用令牌、API密钥或其他身份验证机制来保护API。 ...

  • numpy中怎么改变数组形状

    在NumPy中,可以使用reshape()函数来改变数组的形状。reshape()函数接受一个元组作为参数,该元组表示新数组的形状。
    以下是一个例子:
    import numpy ...