
1. 饿汉式 (在类装载的时候完成实例化)
public class Singleton01 {
private static final Singleton01 singleton ;
static{
// 当类加载器加载的时候直接加载
singleton = new Singleton01();
}
private Singleton01(){}
public static Singleton01 getSingleton(){
return singleton;
}
public static void main(String[] args) {
Singleton01 singleton = Singleton01.getSingleton();
Singleton01 singleton1 = Singleton01.getSingleton();
System.out.println(singleton == singleton1);
}
}
2. 懒汉式 (需要的时候才要加载)
- 最简单的方式 就是 静态内部类
public class Singleton {
//3.构造方法私有化
private Singleton(){}
// 1.写一个静态内部类
private static class SingletonInstance{
private static final Singleton singleton = new Singleton();
}
// 2.实现加载
public static Singleton getInstance(){
return SingletonInstance.singleton;
}
}
- 双重检查 ,进行同步
public class DoubleCheckSingleton {
// 保证可见性
private static volatile DoubleCheckSingleton instance;
private DoubleCheckSingleton(){
}
public static DoubleCheckSingleton getInstance(){
// 检测 1
if (null == instance) {
synchronized (DoubleCheckSingleton.class) {
// 检测 2
if (null == instance) {
instance = new DoubleCheckSingleton();
}
}
}
return instance;
}
}
3. CAS 实现
public class Singleton {
private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<>();
private Singleton() {}
public static Singleton getInstance() {
for (; ; ) {
Singleton singleton = INSTANCE.get();
if (null != singleton) {
return singleton;
}
// 这里可以实例化很多对象
singleton = new Singleton();
// 但是只能设置成功一个对象
if (INSTANCE.compareAndSet(null, singleton)) {
return singleton;
}
}
}
}
5. 对比使用单例模式 和 普通模式内存差异
很显然单例模式 占用内存小
普通的创建对象 ,JVM会自动回收 ,这种方式也很好 , 但是我们知道GC回收, 会全局进行锁操作 ,所以回收很耗时