深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
*
* @Author: Liziba
* @Date: 2021/6/27 16:05
*/
public class LazySingletonTest {
public static void main(String[] args) {
new Thread(() -> run(), “Thread-1”).start();
new Thread(() -> run(), “Thread-2”).start();
System.out.println(“End of test…”);
}
public static void run() {
LazySingletonDemo1 lad = LazySingletonDemo1.getInstance();
System.out.println(Thread.currentThread().getName() + " : " + lad);
}
}
断点设置如下图,邮件打在LAZY_SINGLETON == null的断点上,选择Suspend为Thread,然后点击Done即可。
调试过程,我们执行测试代码,使其两个线程均执行到LAZY_SINGLETON == null,然后F8使得线程1进入if语句;切换至线程2F8进入if语句,此时我们的目的便达到了(在实际的并发使用场景中,这种情况是非常可能出现的)
此时线程1和线程2中的对象并不是同一个对象,所以这种单例编码方式是不正确的。
5.2 同步懒汉式单例
关于上述的单例模式编码,部分读者会想到通过同步原语synchronized加在getInstance()方法上来解决,此时代码如下所示:
package com.lizba.pattern.singleton.lazy;
/**
*
* synchronized修饰方法getInstance()的懒汉式单例
*
*
* @Author: Liziba
* @Date: 2021/6/27 16:37
*/
public class LazySingletonDemo2 {
private static LazySingletonDemo2 LAZY_SINGLETON = null;
private LazySingletonDemo2() {
}
// synchronized修饰getInstance()方法
public static synchronized LazySingletonDemo2 getInstance() {
if (LAZY_SINGLETON == null) {
LAZY_SINGLETON = new LazySingletonDemo2();
}
return LAZY_SINGLETON;
}
}
如上通过给getInstance()加上synchronized关键字,使得同步方法中的代码块线程安全了,但是随之而来的是在大量并发调用该方法的性能问题,大量的线程会阻塞在这个方法上,所以有些我们通过缩小锁锁住的范围来尽可能的提升其并发性能。代码衍生为如下所示:
package com.lizba.pattern.singleton.lazy;
/**
*
* synchronized修饰方法代码块
*
*
* @Author: Liziba
* @Date: 2021/6/27 16:53
*/
public class LazySingletonDemo3 {
private static LazySingleto