背景:已经有很多人总结了,这里做个记录方便之后查看。
直接贴代码,看到的同学复制代码---看注释说明即可
//最优单例问题
public class Singleton {
//1.标准饿汉模式--立即加载
// private static Singleton singletonInstance = new Singleton();
//
// public static Singleton getInstance() {
// return singletonInstance;
// }
private static Singleton singletonInstance;
//2.标准懒汉模式--延迟加载,懒加载,需要的时候才加载
public static synchronized Singleton getInstance() {
if(Beans.isEmpty(singletonInstance)) {
singletonInstance = new Singleton();
}
return singletonInstance;
}
/** 双重校验锁实现对象单例(线程安全)**/
private volatile static Singleton uniqueInstance;
//使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行(volatile 关键字的主要作用就是保证变量的可见性然后还有一个作用是防止指令重排序)
public static Singleton getUniqueInstance1() {
//先判断对象是否已经实例过,没有实例化过才进入加锁代码
if (uniqueInstance == null) {
//类对象加锁
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
//3.最佳单例模式,静态内部类
// 当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。
// 只有当调用 getUniqueInstance() 方法从而触发 SingletonHolder.INSTANCE 时
// SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。
// 这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。
/**这种方式通过jvm来保证其线程安全,而饿加载的机制则是依靠虚拟机规范制度的类“初始化”规则保证**/
public static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getUniqueInstance() {
return SingletonHolder.INSTANCE;
}
// 类初始化规则
// 虚拟机规范则严格规定了有且只有5种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要
// 在此之前开始):
//
// 遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初
// 始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字
// 实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常
// 量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
// 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,
// 则需要先触发其初始化。
// 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父
// 类的初始化。
// 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个
// 类),虚拟机会先初始化这个主类。
// 当使用JDK 1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后
// 的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄
// 所对应的类没有进行过初始化,则需要先触发其初始化。
}
补充:枚举单例
public class EnumSingleton {
private EnumSingleton() {
}
public static EnumSingleton getInstance() {
return Singleton.INSTANCE.getInstance();
}
private static enum Singleton {
INSTANCE;
private EnumSingleton singleton;
// JVM会保证此方法绝对只调用一次
private Singleton() {
singleton = new EnumSingleton();
}
public EnumSingleton getInstance() {
return singleton;
}
}
}
Oracle记录下队列创建
--Create sequence
create sequence PRL_PART_INS_BEN_EXT_SEQ
minvalue 1
maxvalue 999999999999999999999999999
start with 600516
increment by 1
cache 20;