复习了一下java的单例,这里做个笔记,原文地址:https://www.cnblogs.com/zhaoyan001/p/6365064.html
- 饿汉式(静态成员)
public class A{
private A(){}
private static A instance=new A();
public static A getInstance(){
return instance;
}
}
- 饿汉式(静态代码块)
private class A{
private A(){}
private static A instance;
static{
instance=new A();
}
public static A getInstance(){
return instance;
}
}
两种懒汉式都利用了类的加载机制,在类初始化加载时就实例化了对象,这样的好处就是避免了线程同步的问题,缺点就是在直接初始化了这个单例对象,哪怕这个对象没用
- 懒汉式(线程不安全)
public class A {
private static A instance;
private A(){}
public static A getInstance(){
if(instance==null)
instance=new A();
return instance;
}
}
这种单例的实现方式十分简单,在调用getInstance方法后才会调用实例的初始化方法,但如果在多线程情况下,这种方式不安全,可能会创建多个实例化对象。
- 懒汉式(线程安全,同步方法,但效率低)
public class A { private static A instance; private A(){} public synchronized static A getInstance(){ if(instance==null) instance=new A(); return instance; } }
这种单例的实现是在getInstance方法上添加synchronized 关键字,在每次调用方法时都进行同步锁的判断,实现了线程安全,但这种方式由于每次都进行判断,导致效率有所降低
- 懒汉式(线程安全,同步代码块,并不能起到线程安全的作用)
public class A { private static A instance; private A() { } public static A getInstance() { if (instance == null) { synchronized (A.class) { instance = new A(); } } return instance; } }
然后修改为同步代码块,这种方式也不能起到线程安全的作用
- 双重检查(线程安全,懒加载,效率较高,推荐)
public class A { private volatile static A instance; private A() { } public static A getInstance() { if (instance == null) { synchronized (A.class) { if (instance == null) { instance = new A(); } } } return instance; } }
- 静态内部类(线程安全,懒加载,效率高,推荐)
public class A { private A() { } public static A getInstance() { return InnerClass.instance; } private static class InnerClass{ private static final A instance=new A(); } }
在调用getInstance方法时,才会调用内部类,然后完成对单例的初始化
- 枚举(JDK1.5后,使用较少)
public enum A { INSTANCE; public void anyMethod() { } }