应用场景
只需要一个实例:比如Mgr,Factory
饿汉模式
类加载内存后,就实例化一个单例,JVM保证线程安全。简单易懂,方便使用
懒汉模式
虽然达到了按需初始化的目的,但带来了线程不安全的问题。可以通过sychronized对实例方法进行加锁,但是性能会下降。需要加上volitile,避免jvm虚拟机指令重排,在半初始化期返回实例。
可以通过降低锁,将锁方法改成锁代码块提高性能。但是其实并不是单例的,因为仍会有多个线程获得锁。所以需要在代码块锁的内部,再一次判断实例是否为空。在进入实例方法时和锁内部都进行判断。即双重判断。
静态内部类方式
在类中声明静态内部类,返回该类的实例。
加载外部类时,不会加载内部类
JVM保证单例
public class Singleton {
private Singleton(){
}
public static class SingletonHolder{
public final static Singleton single = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.single;
}
public void m(){System.out.println("abc");}
public static void main(String[] args) {
for (int i = 0; i < 50; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton.getInstance().hashCode());
}
}).start();
}
}
}
枚举单例(最完美)
可以解决线程同步,还可以防止反序列化(因为枚举没有构造方法,无法反射出类实例)
public enum Single{
INSTANCE;
}