首页 > 代码库 > 单例实现备忘
单例实现备忘
1. 常见方式
保证线程安全条件下有三种方式:
提前初始化:类加载时就创建一个对象,
延迟初始化
DCL:双重检查,JDK5.0后单例实例加volatile修饰
占位类:推迟占位类的初始化
提前初始化可能影响程序启动时间以及不必要高开销操作较少采用
2. DCL
public class DoubleCheckLocking { private static Resource resource; public static Resource getInstance(){ if(resource == null){ synchronized (DoubleCheckLocking.class){ if (resource == null){ resource = new Resource() } } } return resource } }
上述代码的问题在于在没有同步的情况下读取一个共享对象,可能发生的情况是获取一个没有完成初始化的对象,部分属性是失效的。
在缺少Happens-Before关系时,可能出现指令重排序。初始化对象如果需要写入多个变量,发布对象引用也需要写入一个变量。上述无法保证发布引用在另一个线程加载该引用前,新对象引用的写操作与属性的写操作会重排,这样新线程会看到引用的最新值,但是部分属性失效。
JDK5.0后为resource家volatile修饰可以使用DCL,但是这种方法已经被广泛废弃,占位模式更容易理解
3. 占位类
public class DoubleCheckLocking { private static class ResourceHolder{ public static Resource resource = new Resource(); } public static Resource getInstance(){ return ResourceHolder.resource; } }
本文出自 “Ying:好记性不如烂笔头” 博客,请务必保留此出处http://yingtju.blog.51cto.com/3760152/1921920
单例实现备忘
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。