JUC---11单例模式
Posted jenne-blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JUC---11单例模式相关的知识,希望对你有一定的参考价值。
一、什么是单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
二、代码
1.一般创建
// 饿汉式单例 class Hungry { private Hungry() { } private final static Hungry HUNGRY = new Hungry(); public static Hungry getInstance() { return HUNGRY; } } // 懒汉式单例 class LazyMan { private LazyMan() { } private static LazyMan lazyMan = null; public static LazyMan getInstance() { if (lazyMan == null) { lazyMan = new LazyMan(); } return lazyMan; } }
2.DCL懒汉式------线程安全
一般的懒汉式单例在多线程下会存在问题,因此需要进行操作。加双重检测锁进行检测
// DCL懒汉式单例 class LazyMan { private LazyMan() { System.out.println(Thread.currentThread().getName()); } private volatile static LazyMan lazyMan = null;//避免指令重排 public static LazyMan getInstance() { if (lazyMan == null) { synchronized (LazyMan.class) { if (lazyMan == null) lazyMan = new LazyMan();
} } return lazyMan; } }
为什么要加volatile?因为volatile避免指令重排,在new LazyMan是,这个操作不是一个原子性操作,在执行分配空间(1)、执行构造方法,初始化对象(2)、把这个对象指向这个空间(3)执行这三步时,我们希望执行123,但是经过指令重排后可能是132,;如果此时A线程执行的是132,当B线程执行时,对象已经分配好空间以及指向这个空间,就会认为这个对象不为空,就不在执行,返回这个对象。但是第二步在A线程中还没有执行完,所以造成对象初始化失败,因此要加volatile关键字
3.登记式/静态内部类-------线程安全
class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton() { } public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }
4.枚举-------线程安全
enum Singleton { INSTANCE; public void whateverMethod() { } }
以上是关于JUC---11单例模式的主要内容,如果未能解决你的问题,请参考以下文章