第一篇博客 测试

文章目录

饿汉式

public class Singleton_hungry {
	/*
	 * 饿汉式:一上来就初始化对象,线程安全, 容易产生垃圾对象,类加载是就初始化,浪费内存
	 */
	private static Singleton_hungry singleton = new Singleton_hungry();

	private Singleton_hungry() {
	}

	public static synchronized Singleton_hungry getInstance() {
		return singleton;
	}
}

优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。

懒汉式

public class Singleton_lazy {
// 懒汉式:用的时候创建对象
private static Singleton_lazy singleton;

private Singleton_lazy() {
}

public static synchronized Singleton_lazy getInstance() {
	if (null == singleton) {
		singleton = new Singleton_lazy();
	}
	return singleton;
}

}
优点:第一次调用才初始化,避免内存浪费
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率
双重校验锁

public class Singleton_DCL {
/*
* 采用了双锁机制,安全且在多线程情况下能保持高性能,getSingleton() 的性能对应用程序很关键
*/
private volatile static Singleton_DCL singleton;

private Singleton_DCL() {
}

public static Singleton_DCL getSingleton() {
	if (singleton == null) {
		synchronized (Singleton_DCL.class) {
			if (singleton == null) {
				singleton = new Singleton_DCL();
			}
		}
	}
	return singleton;
}

}

DLC: double-checked locking(双重锁/双重校验锁)
优点:线程安全,延迟加载,效率较高
singleton 采用 volatile 关键字修饰也是很有必要的, singleton = new Singleton_DCL(); 这段代码其实是分
为三步执行:
为 singleton 分配内存空间
初始化 singleton
将 singleton 指向分配的内存地址
但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1->3->2。指令重排在单线程环境下不会出先问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。例如,线程 T1 执行了 1 和 3,此时 T2 调用getUniqueInstance() 后发现 uniqueInstance 不为空,因此返回 uniqueInstance,但此时 uniqueInstance 还未被初始化。使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。
枚举

public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
优点:它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
缺点:当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new,可能会给其他开发人员造成困扰,特别是看不到源码的时候。(在实际工作中,很少使用)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值