Java设计模式——单例模式

本文详细介绍了单例模式的多种实现方式,包括饿汉式、懒汉式、双重同步锁及静态内部类等,并探讨了每种方式的特点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

希望目标类在称程序运行过程中,只有一个实例,无论在哪里用到它,都只是复用同一个实例,而不是创建新的实例,就要用到所谓的单例模式。
单例模式的创建方法有好几种,各有优点,需要灵活使用,才能写出更高效的程序。

饿汉式
直接看代码:

public class Singleton {

    private  static Singleton singleton=new Singleton();
    private Singleton(){}

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

饿汉式适用于单例对象初始化速度快,占用内存小的情况。这就可以用于在程序初始化的时候就要使用单例的情况。相反的,如果单例对象初始化速度较慢,或者占用内存较大,就不推荐使用饿汉式。

懒汉式

public class Singleton {

    private static Singleton singleton = null;

    private Singleton() {
    }

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

顾名思义,懒汉式的特点是:对象初始化的工作会延迟到需要的时候进行。适用于类初始化较慢,内存需求较大,或者是使用场景较少但是重要的情况。

以上2种情况,在单线程情况下,都是安全的。但是,在android开发中经常需要进行多线程处理,这种时候,饿汉式单例不会出错,因为jvm的机制决定了他只会加载一次单例类。但是懒汉式是线程不安全的,有可能造成重复加载。这种情况下,同步锁可以解决问题。

加上同步锁的懒汉式

public class Singleton {

    private static Singleton singleton = null;

    private Singleton() {
    }

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

使用同步锁synchronized (Singleton.class)防止多线程同时进入造成instance被多次实例化,最常用的一种方式 。

一种更好的写法
双重同步锁

public class Singleton {

    private static Singleton singleton = null;

    private Singleton() {
    }

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

在synchronized (Singleton.class)外又添加了一层if判断singleton是否实例化,这是为了在singleton已经实例化后下次进入不必执行synchronized (Singleton.class)获取对象锁,从而提高性能。推荐使用。

静态内部类式

public class Singleton {

    private static class Holder{
        private static Singleton singleton = new Singleton();
    }
    private Singleton() {
    }

    public static Singleton getInstance() {
        return Holder.singleton;
    }

}

这种单例创建方式是利用了JVM的类加载机制的特性:JVM进行类加载的时候他会保证数据是同步的。
创建一个内部类,在内部类中创建需要的对象实例。只要应用中不使用内部类,JVM就不会加载单例类,就不会创建单例对象。从而使恶汉式达到懒汉式的延迟加载目的,又保证了线程的安全,代码还相对简单。推荐使用。

还有一种据说是最简单的方法,但是我没用过。记录下。

public enum  Singleton {
    //定义一个枚举的元素,它就是Singleton的一个实例
    singleton;
    public void doSomething(){

    }
}

使用:

 Singleton singleton=Singleton.singleton;
        singleton.doSomething();

这种方式我目前还没使用过,是Effective Java中推荐的一种更简洁方便的使用方式,即使用枚举。
默认枚举实例的创建是线程安全的。(创建枚举类的单例在JVM层面也是能保证线程安全的),所以不需要担心线程安全的问题,所以理论上枚举类来实现单例模式是最简单的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值