使用静态内部类实现单例
package com.wkcto.sigleton.p3;
import java.util.Random;
/**
* 使用静态内部类实现单例
* 在类加载内存时,就给静态内部类的中的静态变量进行了初始化,具有固有的线程安全性
*/
public class Singleton {
private Singleton(){}
//定义静态内部类,在静态内部类中持有Singleton类实例,并直接初始化
private static class SingletonHandler{
private static Singleton obj = new Singleton();
}
//
public static Singleton getInstance(){
try {
Thread.sleep(new Random().nextInt(50));
} catch (InterruptedException e) {
e.printStackTrace();
}
return SingletonHandler.obj;
}
}
使用静态代码块实现单例
package com.wkcto.sigleton.p5;
/**
* 使用静态代码块实现单例.
* 与饿汉单例没有本质区别,在饿汉单例中会给静态变量显示初始化, 静态变量的显示初始化经过javac编译后会编译到静态代码块中.也是在执行静态代码块时,给饿汉单例的静态实例进行初始化
*/
public class Singleton {
private Singleton(){}
private static Singleton obj;
static {
obj = new Singleton();
}
public static Singleton getInstance(){
return obj;
}
}
使用枚举类型实现的单例
枚举enum和静态代码块的特性相似,在使用枚举时,构造方法会自动调用.单例的枚举实现在书中被作者所推崇,因为功能完善,使用简洁,在面对复杂的序列化或者反射攻击时依然可以防止多次实例化。
package com.wkcto.sigleton.p6;
/**
* 使用枚举类型实现的单例
*/
public class Singleton {
private Singleton(){}
//定义内部枚举类型
private enum SingletonEnum{
//枚举对象天生就是单例
INSTANCE;
private Singleton obj; //定义单例的引用
//在枚举的构造方法中对单例 的引用赋值
SingletonEnum(){
System.out.println("JVM保证枚举类型的构造方法只能调用一次,这是枚举类型的特点");
obj = new Singleton();
}
private Singleton getInstance(){
return obj;
}
}
//提供一个公共的对外接口
public static Singleton getInstance(){
return SingletonEnum.INSTANCE.getInstance();
}
}