单例模式在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问题