二十三种设计模式(第一种)----几种问题较少的单例设计模式写法
单例设计模式之饿汉式
分析:
饿汉式顾名思义比较饥饿 创建类是将对象创建出来了。在多线程条件下可以保证单例。缺点:有点浪费内存空间,问题不大。
代码:
/**
* 饿汉式
* @author TM
* @create 2020-07-24 21:58
*/
public class Hungry {
/**定义静态实例变量 */
private static final Hungry INSTANCE=new Hungry();
/**将构造函数私有化 */
private Hungry(){}
/**提供静态方法 获取实例变量 */
public static Hungry getInstance(){
return INSTANCE;
}
public static void main(String[] args) {
//使用多线程进行测试
for (int i = 0; i < 10; i++) {
new Thread(()-> System.out.println(Hungry.getInstance().hashCode())).start();
}
}
}
单例设计模式之懒汉式(双重检验锁实现)
分析:
懒汉式顾名思义比较懒,使用时才将对象创建出来,为了保证多线程下保持单例,使用双重检验锁来实现。
代码:
/**
* 懒汉式 双重检验
* @author TM
* @create 2020-07-24 22:06
*/
public class Lazy {
/**定义静态私有对象 volatile保证对象的可见性*/
private volatile static Lazy INSTANCE;
/**将构造方法私有化 */
private Lazy() {}
/**创建静态方法获取对象 */
public static Lazy getInstance() {
//1.判断实例是否存在
if (INSTANCE == null) {
//2.保证线程安全 减少锁的粒度
synchronized (Lazy.class) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//3.synchronized 未将1.处if锁住 再次判断对象是否实例
if (INSTANCE == null) {
INSTANCE = new Lazy();
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
//用多线程进行测试
for (int i = 0; i < 10; i++) {
new Thread(()-> System.out.println(Lazy.getInstance().hashCode())).start();
}
}
}
单例设计模式之懒汉式(静态内部类实现)
分析:
懒汉式顾名思义比较懒,使用时才将对象创建出来,为了保证多线程下保持单例,使用静态内部类来实现。
代码:
/**
* 静态内部类
* @author TM
* @create 2020-07-24 22:41
*/
public class StaticInnerClass {
/**构造函数私有化 */
private StaticInnerClass(){}
private static class StaticInnerClassHolder{
/**创建外部类对象 */
private static final StaticInnerClass INSTANCE=new StaticInnerClass();
}
/**获取实例对象 */
public static StaticInnerClass getInstance(){
return StaticInnerClassHolder.INSTANCE;
}
public static void main(String[] args) {
//多线程测试
for (int i = 0; i < 10; i++) {
new Thread(()-> System.out.println(StaticInnerClass.getInstance().hashCode())).start();
}
}
}
单例设计模式之枚举
分析:
枚举支持天然单例。
代码:
public enum SingletonEnum {
INSTANCE;
public static void main(String[] args) {
//多线程测试
for (int i = 0; i < 10; i++) {
new Thread(()-> System.out.println(SingletonEnum.INSTANCE.hashCode())).start();
}
}
}
总结
对于单例的使用,一般情况使用饿汉式即可,简单易理解。