单例模式(线程案例)
- 电脑硬件
- 2025-09-13 23:30:02

单例模式可以分为两种:1.饿汉模式 2.懒汉模式
一.饿汉模式 //饿汉模式👇 class MySingleTon{ //因为这是一个静态成员变量,在类加载的时候,就创建了 private static MySingleTon mySingleTon = new MySingleTon(); //创建一个静态方法,方便在类外获取对象 public static MySingleTon getMySingleTon() { return mySingleTon; } //创建一个私有的构造方法 //避免通过new关键字来调用构造方法,进而创建实例 //保证了唯一性 private MySingleTon(){ } } public class ThreadDemo8 { public static void main(String[] args) { MySingleTon s1 = MySingleTon.getMySingleTon(); MySingleTon s2 = MySingleTon.getMySingleTon(); System.out.println(s1 == s2); } }
程序运行的结果
结果是true,说明了这两次都是获取了同一个实例!,这也说明成功实现了单例模式
因为这个对象是在类加载的时候创建,类加载是单线程的,所以线程安全。但是如果在代码中,没有使用对象,就会造成资源浪费!
二.懒汉模式
这是实现懒汉模式的代码👇
class MySingleTonLazy{ private static MySingleTonLazy mySingleTonLazy = null; public static MySingleTonLazy getMySingleTonLazy() { if(mySingleTonLazy != null){ mySingleTonLazy = new MySingleTonLazy(); } return mySingleTonLazy; } //私有的构造方法 private MySingleTonLazy(){ } } public class ThreadDemo9 { public static void main(String[] args) { MySingleTonLazy s1 = MySingleTonLazy.getMySingleTonLazy(); MySingleTonLazy s2 = MySingleTonLazy.getMySingleTonLazy(); System.out.println(s1==s2); } }这个代码是有两个问题的:1.线程安全问题。2.指令重排序问题
1.线程安全问题所以说,需要对其加锁。把这些指令打包成一个原子(整体),这样就不会出现这种情况了。
这是修改后的代码,是线程安全的!
第一个if是用来判断这个实例是否已经创建了,如果创建就直接跳过这个代码了。👆
2.指令重排序问题 mySingleTonLazy = new MySingleTonLazy()
这行代码在执行的时候,会分为3个步骤:
1.分配内存空间
2.初始化对象
3.将引用指向对象
这3个步骤可以是按132顺序执行,也可以是123顺序执行👇
如果是按132来执行的,先执行完1,然后执行3 ,在执行完3后,另一个线程也来执行,因为已经创建了对象,在if判断完后,直接跳过去了,但此时这个对象没有初始化,故而会有空指针问题
那么我们该如何解决这个问题👇
引入volatile关键字
1.防止内存可见性问题
2.解决指令重排序问题
此时这个volatile 解决指令重排序问题
private volatile static MySingleTonLazy mySingleTonLazy = null;那么这懒汉模式正确代码如下👇
class MySingleTonLazy { // 使用 volatile 修饰,保证可见性和禁止指令重排序 private volatile static MySingleTonLazy mySingleTonLazy = null; private static Object locker = new Object(); public static MySingleTonLazy getMySingleTonLazy() { // 第一次检查,判断实例是否已经创建 if (mySingleTonLazy == null) { // 加锁,保证线程安全 synchronized (locker) { // 第二次检查,防止多个线程同时通过第一次检查 if (mySingleTonLazy == null) { mySingleTonLazy = new MySingleTonLazy(); } } } return mySingleTonLazy; } // 私有的构造方法,防止外部实例化 private MySingleTonLazy() { } } public class ThreadDemo9 { public static void main(String[] args) { MySingleTonLazy s1 = MySingleTonLazy.getMySingleTonLazy(); MySingleTonLazy s2 = MySingleTonLazy.getMySingleTonLazy(); System.out.println(s1 == s2); } }总结:
线程安全:
饿汉模式:天生都线程安全,不用如何处理
懒汉模式:线程不安全,需要自己处理
资源利用率:
饿汉模式:那么创建出了这个实例,然后并没有使用这个实例,这就造成了资源浪费的情况
懒汉模式:用的时候,创建实例,避免不必要的资源浪费的情况。
单例模式(线程案例)由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“单例模式(线程案例)”
上一篇
视频流畅播放相关因素
下一篇
MySQL数据库的数据类型