单例模式(singleton)
饿汉式(推荐,满足大部分情况)
public class Mgr01 {
// 类加载时就实例化一个对象
private static final INSTANSCE = new Mgr01();
// 将构造方法私有化,他人就无法new出来一个新的对象
private Mgr01(){};
// 只能通过方法来获取对象
public static Mgr01 getInstance() { return INSTANSCE; };
}
类加载到内存后,就实例化一个对象,由JVM保证线程安全。
缺点:不管是否使用,类装载的时候都会实例化。
懒汉式(线程不安全)
public class Mgr02 {
private static INSTANSCE;
private Mgr02(){};
public static Mgr02 getInstance() {
if(INSTANSCE == null){
INSTANSCE =new Mgr02();
}
return INSTANSCE;
}
虽然达到了按需实例化的目的,但是带来的线程不安全的问题。如果多个线程同时访问getInstance(),可能会new出来多个不同的实例化对象。
模拟多线程访问,打印出来了不同的hashcode。
懒汉式(synchronized锁方法,不推荐)
public class Mgr03 {
private static INSTANSCE;
private Mgr03(){};
public static synchronized Mgr03 getInstance() {
if(INSTANSCE == null){
INSTANSCE =new Mgr03();
}
return INSTANSCE;
}
虽然解决了线程安全的问题,但是导致性能下降很多。
懒汉式(双重验证法,推荐)
public class Mgr04 {
private static INSTANSCE;
private Mgr04(){};
public static synchronized Mgr04 getInstance() {
if(INSTANSCE == null){
synchronized (Mgr04.class) {
if(INSTANSCE == null){
INSTANSCE =new Mgr04();
}
}
}
return INSTANSCE;
}
缩小锁的范围,双重检查保证安全。
懒汉式(静态内部类方式,高级写法)
public class Mgr05 {
private Mgr05(){};
// 静态内部类在外部类加载的时候不会被加载
private static class Mgr05Holder(){
private final static INSTANSCE = new Mgr05();
}
// 调用getInstance()时内部类才会被加载
public static Mgr05 getInstance() { return Mgr05Holder.INSTANSCE; };
}
此写法即实现了单例,又实现懒加载,同时由JVM保证线程安全。
终极写法 (尚未理解)ヽ(゚Д ゚; )ノ
public enum Mgr06 {
INSTANSCE;
}
此写法由java创始人之一所写,不仅解决线程同步,还可以防止序列化。