博客
关于我
单例模式
阅读量:224 次
发布时间:2019-03-01

本文共 3591 字,大约阅读时间需要 11 分钟。

文章目录

1 饿汉式

/** * @author :wyaoyao * @date : 2020-04-06 14:32 * 单例模式:饿汉式 * 线程安全 * 但是在不使用的时候占用内存,因为通过static是类主动加载,不能能够懒加载 */public class SingletonSimple1 {       private static final SingletonSimple1 instance = new SingletonSimple1();    // 构造私有化。不允许外部调用    private SingletonSimple1() {       }    public static SingletonSimple1 getInstance() {           return instance;    }}
  • 线程安全
  • 但是在不使用的时候占用内存,通过static是类主动加载,不能能够懒加载

测试

// 测试@Testpublic void test() {       SingletonSimple1 instance1 = SingletonSimple1.getInstance();    SingletonSimple1 instance2 = SingletonSimple1.getInstance();    Assert.assertTrue(instance1 == instance2);}

懒汉式

/** * @author :wyaoyao * @date : 2020-04-06 14:41 * 饿汉式:懒加载 */public class SingletonSimple2 {       private static SingletonSimple2 instance;    private SingletonSimple2(){       }    // 存在线程安全问题    public static SingletonSimple2 getInstance(){           if(null == instance){               instance = new SingletonSimple2();        }        return instance;    }}
  • 这个懒加载,在使用的时候才会创建对象,但是线程不安全

测试

// 测试,构建100线程去创建对象,测试是否线程安全@Testpublic void test2() {       for (int i = 0; i<100; i++){           new Thread(()->{               SingletonSimple2 instance = SingletonSimple2.getInstance();            System.out.println(instance);        },"T"+i).start();    }    /**     * 不安全,并不是单例的,SingletonSimple2@608f35ee,SingletonSimple2@5617e729     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@608f35ee     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@5617e729     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@7df5ed4e     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@7df5ed4e     * study.wyy.concurrency.designpatterns.singleton.SingletonSimple2@7df5ed4e     */}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jSHdx6qg-1599738853607)(evernotecid://FA2713E9-40BE-49E5-BF9D-E3ACD77E4128/appyinxiangcom/21741088/ENResource/p542)]

解决懒汉式的线程不安全

方案一

// 加锁    public synchronized static SingletonSimple2 getInstance(){           if(null == instance){               instance = new SingletonSimple2();        }        return instance;    }

问题

  • 除了第一次是创建,以后都是读的操作,每次都会加锁,效率不高

方案二

double check

public class SingletonSimple3 {       private static SingletonSimple3 instance;    private SingletonSimple3(){       }    public static  SingletonSimple3 getInstance(){           if(null == instance){               synchronized (SingletonSimple3.class){                   if(null == instance){                       instance = new SingletonSimple3();                }            }        }        return SingletonSimple3.instance;    }}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D4qVca7W-1599738853614)(evernotecid://FA2713E9-40BE-49E5-BF9D-E3ACD77E4128/appyinxiangcom/21741088/ENResource/p543)]

也存在问题:可能会引起npe

解决这个问题很简单,使用volatile关键字即可

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

ClassHolder

  • 支持懒加载
  • 线程安全
  • 不会npe
public class SingletonSimple5 {       private SingletonSimple5(){       }    private static class InstanceHolder {           private final static SingletonSimple5 instance = new SingletonSimple5();    }    public static SingletonSimple5 getInstance(){           return InstanceHolder.instance;    }}

枚举方式

转载地址:http://obrv.baihongyu.com/

你可能感兴趣的文章
mysql 添加索引
查看>>
MySQL 添加索引,删除索引及其用法
查看>>
mysql 状态检查,备份,修复
查看>>
MySQL 用 limit 为什么会影响性能?
查看>>
MySQL 用 limit 为什么会影响性能?有什么优化方案?
查看>>
MySQL 用户权限管理:授权、撤销、密码更新和用户删除(图文解析)
查看>>
mysql 用户管理和权限设置
查看>>
MySQL 的 varchar 水真的太深了!
查看>>
mysql 的GROUP_CONCAT函数的使用(group_by 如何显示分组之前的数据)
查看>>
MySQL 的instr函数
查看>>
MySQL 的mysql_secure_installation安全脚本执行过程介绍
查看>>
MySQL 的Rename Table语句
查看>>
MySQL 的全局锁、表锁和行锁
查看>>
mysql 的存储引擎介绍
查看>>
MySQL 的存储引擎有哪些?为什么常用InnoDB?
查看>>
Mysql 知识回顾总结-索引
查看>>
Mysql 笔记
查看>>
MySQL 精选 60 道面试题(含答案)
查看>>
mysql 索引
查看>>
MySQL 索引失效的 15 种场景!
查看>>