专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java设计模式之单例模式的十面埋伏

temp10 2025-06-09 00:06:14 java教程 4 ℃ 0 评论

Java设计模式之单例模式的十面埋伏

在Java的世界里,设计模式就像武林秘籍,掌握了它,你就能在编程江湖中游刃有余。其中,单例模式绝对是秘籍中的经典招式之一。今天,咱们就来聊聊单例模式的十种实现方式,看看它们各自的优劣,保证让你笑中带泪,泪中带笑。


Java设计模式之单例模式的十面埋伏


单例模式:江湖上的独孤求败

单例模式的定义很简单,就是确保一个类只有一个实例,并且提供一个全局访问点。听起来是不是有点像“天下武功,唯快不破”?但实际上,实现起来却有许多讲究。

第一式:饿汉式

饿汉式的单例模式是最简单直接的一种实现。在类加载的时候就创建好实例,代码如下:

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

    private Singleton() {}

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

优点:简单明了,线程安全。 缺点:不管用不用,都会创建实例,浪费资源。

第二式:懒汉式(线程不安全)

懒汉式顾名思义,只有在需要的时候才去创建实例。但如果不加同步,那就会变成线程不安全的代码:

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

优点:按需创建,节约资源。 缺点:线程不安全,容易出错。



第三式:懒汉式(线程安全)

为了确保线程安全,我们可以给getInstance方法加上同步锁:

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

优点:线程安全。 缺点:效率低,每次都需要同步。

第四式:双重检查锁定

这种实现方式利用了双重检查锁定机制,在提高效率的同时保证线程安全:

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

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

优点:高效,线程安全。 缺点:复杂度稍高。

第五式:静态内部类

利用静态内部类的特点,在需要时才加载实例,既安全又高效:

public class Singleton {
    private Singleton() {}

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

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

优点:高效,线程安全。 缺点:稍微有点绕。

第六式:枚举

使用枚举来实现单例模式,是最简单也是最安全的方式之一:

public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("Doing something...");
    }
}

优点:线程安全,防止反序列化破坏单例。 缺点:灵活性稍差。

第七式:克隆模式

通过覆盖clone方法,来防止对象被克隆:

public class Singleton implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}

优点:防止对象被克隆。 缺点:需要手动处理,不够优雅。

第八式:双重校验锁(DCL)+volatile

为了防止指令重排带来的问题,可以在双重检查锁定的基础上加上volatile关键字:

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

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

优点:高效,线程安全。 缺点:复杂度高。

第九式:静态代码块

利用静态代码块初始化实例,也是一种常见的实现方式:

public class Singleton {
    private static Singleton instance;

    static {
        instance = new Singleton();
    }

    private Singleton() {}

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

优点:简单易懂。 缺点:不够灵活。

第十式:静态工厂方法

通过静态工厂方法来获取实例,这种方式在某些场景下非常有用:

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

    private Singleton() {}

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

优点:封装性好。 缺点:不够灵活。

总结

通过这十种不同的实现方式,我们可以看到,单例模式虽然看起来简单,但其实有非常多的变化和讲究。每一种实现都有其适用的场景和局限性,我们需要根据具体的需求来选择最合适的方式。

希望这篇文章能让你对单例模式有更深刻的理解,同时也希望能带给你一些乐趣。记住,编程不仅仅是工作的工具,更是一种生活的艺术!


本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表