1.、单例模式
sun.misc.Unsafe中的单例模式
private static final Unsafe theUnsafe = new Unsafe();
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
可以看到,Unsafe类为一单例实现,提供静态方法getUnsafe获取Unsafe实例,当且仅当调用getUnsafe方法的类为引导类加载器所加载时才合法,否则抛出SecurityException异常。
那么如果我们要在自己的类中使用Unsafe类怎么办呢?一种是通过Java命令行命令-Xbootclasspath/a
把调用Unsafe相关方法的类A所在jar包路径追加到默认的bootstrap路径中,使得A被引导类加载器加载,从而通过Unsafe.getUnsafe
方法安全的获取Unsafe实例。另一种就是通过放射获取单例对象theUnsafe。
private static Unsafe getUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe)field.get(null);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
java.util.UUID类中的单例模式
public final class UUID implements java.io.Serializable, Comparable<UUID> {
private static class Holder {
static final SecureRandom numberGenerator = new SecureRandom();
}
public static UUID randomUUID() {
SecureRandom ng = Holder.numberGenerator;
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
}
可以看到这里使用了内部类的方式来实现了单例模式,这种实现具有延迟加载的功能,且由于类只会被加载一次,所以也是线程安全的。