单例模式

饿汉式

在声明时随着类的加载就加载到内存中

public class Ehan {
    private static final Ehan INSTANCE = new Ehan();
    private Ehan() {}
    public Ehan getINSTANCE() {
        return INSTANCE;
    }
}

注意
1.类的构造器是私有的
2.唯一实例化类用static和final修饰,static保证随着类的加载而初始化,final保证对象不会被修改
3.声明一个get方法,获取该单例的实例

懒汉式

饿汉式有一个很明显的问题,那就是无论是否需要,都会被加载到内存中,为了解决这个问题就产生了懒汉式

public class LHan {
    private static volatile LHan lHan = null;
    public static LHan getInstance() {
        if (lHan == null) {
            synchronized (LHan.class) {
                if (lHan == null) {
                    lHan = new LHan();
                }
            }
        }
        return lHan;
    }
}

注意
1.懒汉式不会再类的加载过程中被实例化,而是实际需要的过程中去创建。
2.创建时需要应对线程安全,且注意内层的判空,没有内层判空等于没有加锁。
3.单例对象最好声明为volatile的,因为如果开启了JIT,JVM优化之后,本地代码重排,可能导致未被初始化就返回INSTANCE的情况

枚举处理单例

在effective java中引入改了方法实现单例

public enum Mj {
    INSTANCE;
    private String name = "JayHoo";
    public String getName() {
        return name;
    }
    public static void main(String[] args) {
        System.out.println(Mj.INSTANCE.getName());
    }
}

书中对该方法的说法是

这种方法在功能上与公有方法相似,但更加简洁,无偿地提供了序列化机制,绝对防止多次实例化,即使是在面对复杂的序列化或者反射攻击的时候。虽然这种方法还没有广泛采用,但是单元素的枚举类型经常成为实现Singleton的最佳方法。注意,如果Singleton必须扩展一个超类,而不是扩展Enum的时候,则不适宜使用这个方法。

其实,这个方法本身也是使用了枚举对象会随着类加载而加载,让JVM实现单例以及保证线程安全。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。