单例模式(singleton)

至此,我们已经学会了单例模式的“饿汉模式”,让太阳一开始就准备就绪,随时供应免费日光。然而,如果始终没人获取日光,那岂不是白造了太阳,一块内存区域被白白地浪费了?这正类似于商家货品滞销的情况,货架上堆放着商品却没人买,白白浪费空间。因此,商家为了降低风险,规定有些商品必须提前预订,这就是“懒汉模式”(lazy initialization)。沿着这个思路,我们继续对太阳类进行改造,

1.  public class Sun {
2.  
3.      private static Sun sun;//这里不进行实例化
4.  
5.      private Sun(){//构造方法私有化
6.      
7.      }
8.  
9.      public static Sun getInstance() {
10.         if (sun == null) {//如果无日才造日
11.             sun = new Sun();
12.         }
13.         return sun;
14.     }
15.  
16. }

可以看到我们一开始并没有造太阳,所以去掉了关键字final,只有在某线程第一次调用第9行的getInstance()方法时才会运行对太阳进行实例化的逻辑代码,之后再请求就直接返回此实例了。这样的好处是如无请求就不实例化,节省了内存空间;而坏处是第一次请求的时候速度较之前的饿汉初始化模式慢,因为要消耗CPU资源去临时造这个太阳(即使速度快到可以忽略不计)。
这样的程序逻辑看似没问题,但其实在多线程模式下是有缺陷的。试想如果是并发请求的话,程序第10行的判空逻辑就会同时成立,这样就会多次实例化太阳,并且对sun进行多次赋值(覆盖)操作,这违背了单例的理念。我们再来改良一下,把请求方法加上synchronized(同步锁)让其同步,如此一来,某线程调用前必须获取同步锁,调用完后会释放锁给其他线程用,也就是给请求排队,一个接一个按顺序来

1.  public class Sun {
2.  
3.      private static Sun sun;//这里不进行实例化
4.  
5.      private Sun(){//构造方法私有化
6.      
7.      }
8.  
9.      public static synchronized Sun getInstance() {//此处加入同步锁
10.         if (sun == null) {//如果无日才造日
11.             sun = new Sun();
12.         }
13.         return sun;
14.     }
15.  
16. }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值