单例的理解

单例的理解

hi, 大家好,我是爱吃香蕉的猴子,今天看到郭神之前的一篇文章膜拜,关于使用单例的,自己有些感触,就借鉴写一下记录.


延续大神的例子:
第一版
不使用单例,new的太多,占用内存,不可取;
第二版

public class LogUtil {
	private static LogUtil sLogUtil; 
	public static LogUtil getInstance() {
	                                             //1
		if (sLogUtil == null) {                 //2
		                                        //3
			sLogUtil = new LogUtil();          //4
		} 
		                                     / /5
		return sLogUtil;
	}
}
LogUtil.getInstance().debug("Hello World");

这种方式,如果在多线程模式下,如果thead B、thread A, 在3位置 这样,thread A初始化了,thread B也会初始化,这样也会出现两个实例,则需要增加锁。
第三版

	private static LogUtil sLogUtil;
	public synchronized static LogUtil getInstance() {
		if (sLogUtil == null) {
			sLogUtil = new LogUtil();
		}
		return sLogUtil;
	}

在方法上加上synchronized,线程排队执行,每次执行getInstance都要受锁影响,这样效率相对低一些;
第四版

	private static LogUtil sLogUtil;
	public static LogUtil getInstance() {
		synchronized (LogUtil.class) {
			if (sLogUtil == null) {
				sLogUtil = new LogUtil();
			}
			return sLogUtil;
		}
	}```
在方法内增加类锁,但是:如果theadA threadB都在锁外,已经初始化的也在排队,是否可以增加判断;
*第五版*

private static LogUtil sLogUtil;

public static LogUtil getInstance() {
	if (sLogUtil == null) {
		//没有初始化的排队
		synchronized (LogUtil.class) {
			if (sLogUtil == null) {
				sLogUtil = new LogUtil();
			}
		}
	}
	return sLogUtil;

这样,代码改成这样之后,基本完善了,但是在线程A中sLogUtil实例化了,在线程B中是可见的吗?
第六版

	private volatile static LogUtil sLogUtil;
	public static LogUtil getInstance() {
		                                             / /0
		if (sLogUtil == null) {                      // 1
			                                         //2
			synchronized (LogUtil.class) {           // 3
			                                         //4
				if (sLogUtil == null) {             // 5
					                                   //6 
					sLogUtil = new LogUtil();         //7
				}
			}
		}
		return sLogUtil;
  }

增加了Volatile [ˈvɒlətaɪl] ,这样线程间可见;
这样,算是完整了。


有人问我,为什么5还要加一次判断?
我是这样认为的,在ThreadA 执行了7,这个时候,TheadB执行到3进入4,这种场景,自然就需要增加一次判断;

还有人提出过,为什么不用枚举,这个方案虽然是java里面被推荐的,但 个人认为不适合android, 因为枚举还是站用内存较大的。
为什么枚举占内存大


                                  Code的搬运工V1.o
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值