单例模式
来源:互联网 发布:淘宝美工做什么的 编辑:程序博客网 时间:2024/06/08 11:36
http://jameswxx.iteye.com/blog/1054992
单例模式?多么简单!也许吧,可是要通过简单的现象,看到问题的本质,就比较难,知其然而不知其所以然,这种态度不好。
一:看看最简单的
- <span style="font-size: small;">public class SingleInstance{
- private static instance=new SinleInstance();
- public static SingleInstance getInstance(){
- return instance;
- }
- }</span>
这个很明了,也确实会返回唯一的实例,但是如果我永远都不会用到SingleInstance.getInstance(),instance这个对象却一直存在,占用了内存空间,浪费。
二:那就不先实例化
- public class SingleInstance{
- private static SingleInstance instance;
- public static SingleInstance getInstance(){
- if(instance==null){
- instance=new SingleInstance();
- }
- return instance;
- }
- }
表面上,这个似乎是可行的。但是很显然,在多线程并发环境中,可能会创建两个instance,也有可能一个线程拿到的instance是一个不完整的实例。
三:好吧,那我加上同步总可以吧
- public class SingleInstance{
- private static SingleInstance instance;
- public static synchronized SingleInstance getInstance(){
- if(instance==null){
- instance=new SingleInstance();
- }
- return instance;
- }
- }
这个虽然不会有内存上的浪费,但是有同步锁住了整个class,会降低系统的性能。按照数据结构的说法,就是一个提高了空间复杂度,一个提高了时间复杂度。
四:最佳实践
比较好的做法
- public class SingleInstance {
- private static class InstanceHolder {
- public static final SingleInstance instance = new SingleInstance();
- }
- public static SingleInstance getInstance() {
- return InstanceHolder.instance;
- }
- }
这种Holder做法保证了实例在用到的时候才会创建,而且创建的实例肯定是唯一的。
五:所谓的DCL
下面这种做法是广为流传的所谓DCL(双重检查锁定)做法,这是没有正确理解java内存模型造成的,只保证了创建实例的原子性,而没有解决共享资源的可见性。
- <pre class="java" name="code"><span style="font-size: small;">public class SingleInstance{
- private static SingleInstance instance;
- public static SingleInstance getInstance(){
- if(instance==null){
- synchronized(SingleInstance.class){
- if(instance==null){
- instance=new SingleInstance();
- }
- }
- }
- return instance;
- }
- }
- </span>
- </pre>
表面上看,这个似乎确实没有什么问题呢,其实还是有问题的,虽然概率比较小,要深刻的理解为什么,必须要对java内存模型比较熟悉。对于instance的创建,某个时刻某个线程拿到了同步锁,将instance创建了,并且及时写回了主存。但是对于另一个线程而言,它不能及时“看到”instance变量的最新值。它的instance可能是工作内存里的而不是主内存里的,甚至更为糟糕的情况是,instance是主内存的,可它的某些属性是工作内存的,这会导致程序发生莫名其妙不可捉摸的错误。在平台级框架里,这会造成系统在高并发环境下不稳定,甚至造成致命的错误 。
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- [设计模式] 单例模式
- 海浪
- Unity截屏
- Palindrome Number
- Ubuntu下Qt与Mysql驱动问题解决
- Please ensure that adb is correctly located at 最新详细方案
- 单例模式
- Deadlock的一些总结
- myeclipse8.5安装svn插件(方法一)
- python paramiko链接linux执行命令操作
- 正则表达式
- Y344封隔器
- struts 1 中 <html:form>详解
- Gson的详细使用
- 基于内容的视频信息检索系统