标签:单例 优点 sync 对象 代码 全局 img 编译 多重
保证一个类仅有一个实例,并提供一个全局访问点
创建型
想确保任何情况下都绝对只有一个实例
在内存里只有一个实例,减少了内存开销。
可以避免对资源的多重占用。
设置全局访问点,严格控制访问。
没有接口,扩展困难
在需要的时候才实例化对象。
但是这种模式会存在线程安全问题。
代码如下:
public class LazySingleton {
private static LazySingleton lazySingleton = null;
/**
* 私有构造器
*/
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
public class LazyDoubleCheckSingleton {
private static volatile LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null;
private LazyDoubleCheckSingleton() {
}
public static LazyDoubleCheckSingleton getInstance() {
if (lazyDoubleCheckSingleton == null) {
synchronized (LazyDoubleCheckSingleton.class) {
if (lazyDoubleCheckSingleton == null) {
lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
}
}
}
return lazyDoubleCheckSingleton;
}
}
JVM创建对象有以下几步:
1、给对象分配内存空间;
2、初始化对象;
3、设置实例
指向刚分配的内存地址;
4、初次访问对象。
但是在实际的创建对象的过程中,2,3两步有可能出现指令重排,也就是先执行3,2的顺序,这种改变在单线程中是没有问题的,实际在多线程中也没太大的问题,只是出现极端情况下,会出现问题,如下图所示:
volatile
有两个作用:内存可见性和禁止指令重排。在这段代码中保证了指令的顺序性,不会重排序。
标签:单例 优点 sync 对象 代码 全局 img 编译 多重
原文地址:https://www.cnblogs.com/xiaotutu365/p/10367496.html