实现方式
一、饿汉式
介绍:初试化静态的instance创建一次;
注意点
1、构造器私有;
2、提供静态变量;
3、提供方法;
简单实现
public class Singleton {
private Singleton() {
System.out.println("私有化构造器");
}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
return INSTANCE;
}
}
存在问题及优化
1、反射攻击:添加判断防止反射攻击;
2、如果实现Serializable接口可以反序列化攻击:重写readResolve()方法,返回实例;
3、jdk内部类Unsafe(无解);
public class Singleton implements Serializable {
private Singleton() {
// 添加判断防止反射攻击
if(INSTANCE!=null){
throw new RuntimeException("单例对象不能重复创建");
}
System.out.println("私有化构造器");
}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
return INSTANCE;
}
public Object readResolve(){
return INSTANCE;
}
}
二、枚举饿汉式
简单实现
public enum Singleton{
INSTNCR;
}
存在问题
jdk内部类Unsafe(无解);
三、懒汉式
介绍:第一次调用时创建;
注意点
1、构造器私有;
2、提供静态变量,先置为null;
3、提供方法:对静态变量添加判断;
简单实现
public class Singleton {
private Singleton() {
System.out.println("私有化构造器");
}
private static Singleton INSTANCE = null;
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
存在问题及优化
多线程下线程不安全:添加synchronized关键字
public class Singleton {
private Singleton() {
System.out.println("私有化构造器");
}
private static Singleton INSTANCE = null;
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
四、DCL(双检锁)懒汉式
介绍:优化多线程下访问问题;利用volatile 关键字(保证可见性,有序性)防止指令重排;
public class Singleton {
private Singleton() {
System.out.println("私有化构造器");
}
private static volatile Singleton INSTANCE = null;
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
五、内部类懒汉式(推荐使用)
简单实现
public class Singleton {
private Singleton() {
System.out.println("私有化构造器");
}
private static class innerClas {
static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return innerClas.INSTANCE;
}
}
在JDK中使用
System类
1、Runtime():System类中调用exit()和gc()时,使用Runtime()方法;
2、cons:System类中调用console(),获取cons实例(使用双检锁);
Collections类
1、EmptyNavigableSet(内部类懒汉式)
2、EmptyIterator(内部类懒汉式)
3、ListIterator(内部类懒汉式)
5、Enumeration(内部类懒汉式)
6、EmptySet(饿汉式)
7、EmptyList(饿汉式)
8、Compartor(枚举饿汉式)