单例模式的五种方式
主要:懒汉式,饿汉式
其他:双重检测锁(Double Checking模式),静态内部类,枚举模式
选取时机
延时加载,占用内部资源大:静态内部类好于懒汉
不延时加载,占用内部资源小:枚举好于饿汉
/**
* 单例模式 懒汉式
* @author 小帆敲代码
*
*/
public class Demo01 {
//类加载时,不初始化(可以延时加载)
private static Demo01 instance;
private Demo01(){
}
//上锁,并发效率低
public static synchronized Demo01 getInstance() {
if(instance==null) {
instance=new Demo01();
}
return instance;
}
}
/**
* 单例模式 饿汉式
* @author 小帆敲代码
*
*/
public class Demo02 {
//类加载时,对象就被初始化(不可以延时加载),天然的线程安全,并发效率高
private static Demo02 instance=new Demo02();
private Demo02(){
}
//不上锁,并发效率高
public static Demo02 getInstance() {
return instance;
}
}
/**
* 双重检测 Double checking
* 问题 指令重排和JVM内部模型不支持可能会带来问题
* 解决方法:volatile取消指令重排
* @author 小帆敲代码
*
*/
public class Demo03 {
private /* volatile*/ static Demo03 instance=null;
private Demo03() {
}
public static Demo03 getInstance() {
//double checking
if(null==instance) {
//只在第一次创建时锁
synchronized(Demo03.class) {
if(null==instance)
instance=new Demo03();
}
}
return instance;
}
}
/**
* 静态内部类实现单例模式
* 线程安全,效率高,延迟加载
* @author 小帆敲代码
*
*/
public class Demo04 {
//外部类没有static属性,只有在被使用时才会被加载内部类
private static class SingleDemo04{
private static /*final*/ Demo04 instance=new Demo04();
}
private Demo04() {
}
public static Demo04 getInstance() {
return new SingleDemo04().instance;
}
}
/**
* 枚举模式实现单例
* 保证只有一个,线程安全,天然的防止反射和反序列化的漏洞
* 不能延时加载
* @author 小帆敲代码
*
*/
public enum Demo05 {
//只有一个实例
INSTANCE;
//其他操作
public void dosomething() {
}
}