工作深度总结——双重锁定实现单例
Posted 喵喵7781
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工作深度总结——双重锁定实现单例相关的知识,希望对你有一定的参考价值。
代码段
private static volatile OSSClient ossClient;
private static OSSClient getOssClient()
if (ossClient == null)
synchronized (OSSClient.class)
if (ossClient == null)
ossClient = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
Runtime.getRuntime().addShutdownHook(new Thread(() -> ossClient.shutdown()));
return ossClient;
关键代码解析
原子性
synchronized 确保当前只有一个线程实例化oss客户端
可见性
volatitle 全局共享变量,在Java5之后,遵循happens-before原则,一旦被改变,立刻写入内存,写优先于读。
有序性
synchronized 保证了线程的有序性
钩子
已经初始化,但是并不启动的线程,jvm退出之前,进行ossClient的关闭。
代码逻辑解析
首先判断ossClient是否为空,如果不为空,就直接返回;如果为空,就先锁定当前的类,允许一个线程进入。
然后再次判断ossClient是否被初始化。如果没有被初始化,就new 一个ossClient;如果被初始化,就直接返回实例化对象。
如果没有通过volatitle 修饰,可能会报错,因为JVM主要进行三个操作:1.给 ossClient 分配内存 2.调用 Singleton 的构造函数来初始化成员变量
3. 将ossClient对象指向分配的内存空间(执行完这步ossClient就为非 null 了),2和3的操作顺序未知,如果先进行3,然后再进行2操作,ossClient不为空,
2还没有完成,返回就会报错。
Java5之后,通过volatitle修饰,保证写优先于读,所以如果判断ossClient 不为空,那么初始化一定完成。
总结
编写优秀的代码,就像欣赏一首美妙的歌曲,美好的事物,谁不喜欢呢~
以上是关于工作深度总结——双重锁定实现单例的主要内容,如果未能解决你的问题,请参考以下文章