0
点赞
收藏
分享

微信扫一扫

【设计模式】单例模式——JDK源码中的单例模式

单例模式在JDK源码中的应用比较广泛


Runtime

Runtime 类是 Java 标准库中的关键类之一。它提供了对当前Java虚拟机(JVM)实例的访问和控制,代表了正在执行Java应用程序的运行时环境。Runtime 类封装了访问底层系统和控制JVM行为的方法,使得程序能够与运行时环境进行交互。

/**
 * Every Java application has a single instance of class
 * <code>Runtime</code> that allows the application to interface with
 * the environment in which the application is running. The current
 * runtime can be obtained from the <code>getRuntime</code> method.
 * <p>
 * An application cannot create its own instance of this class.
 */
public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    // ……代码省略……

    /**
     * Returns the runtime object associated with the current Java application.
     * Most of the methods of class <code>Runtime</code> are instance
     * methods and must be invoked with respect to the current runtime object.
     *
     * @return  the <code>Runtime</code> object associated with the current
     *          Java application.
     */
    public static Runtime getRuntime() {
        return currentRuntime;
    }

    /** Don't let anyone else instantiate this class */
    private Runtime() {}
    
    // ……代码省略……
}

当用户打开 Runtime类的代码就会发现,在这个类中唯一的构造方法是被private修饰的,所以Runtime类是一个典型的饿汉式单例模式。


Unsafe 

Unsafe类是一个位于sun.misc包下的类,它提供了一些相对底层方法,能够让我们接触到一些更接近操作系统底层的资源,如系统的内存资源、cpu指令等。而通过这些方法,我们能够完成一些普通方法无法实现的功能,例如直接使用偏移地址操作对象、数组等等。但是在使用这些方法提供的便利的同时,也存在一些潜在的安全因素,例如对内存的错误操作可能会引起内存泄漏,严重时甚至可能引起JVM崩溃。

public final class Unsafe {

    static {
        Reflection.registerMethodsToFilter(Unsafe.class, Set.of("getUnsafe"));
    }

    private Unsafe() {}

    private static final Unsafe theUnsafe = new Unsafe();
    private static final jdk.internal.misc.Unsafe theInternalUnsafe = jdk.internal.misc.Unsafe.getUnsafe();

    /**
     * Provides the caller with the capability of performing unsafe
     * operations.
     *
     * <p>The returned {@code Unsafe} object should be carefully guarded
     * by the caller, since it can be used to read and write data at arbitrary
     * memory addresses.  It must never be passed to untrusted code.
     */
    @CallerSensitive
    public static Unsafe getUnsafe() {
        Class<?> caller = Reflection.getCallerClass();
        if (!VM.isSystemDomainLoader(caller.getClassLoader()))
            throw new SecurityException("Unsafe");
        return theUnsafe;
    }
 
}

从以上代码中可以看出,Unsafe被final修饰不允许被继承,并且构造函数为private类型,即不允许我们手动调用构造方法进行实例化,这是很典型的饿汉式单例模式。


值得注意的是,在Android SDK源码对CAS以及其他很多底层功能的实现中,Unsafe类是被抽象类VarHandle取代的,而VarHandle的所有子类都没有应用到单例模式。


单例模式在JDK源码中一般以饿汉式的形式出现,因为JDK源码中的很多对象的生命周期贯穿应用的生命周期始终,所以不需要考虑GC问题





举报

相关推荐

0 条评论