首页 > 其他 > 详细

单例模式

时间:2014-04-13 14:45:57      阅读:342      评论:0      收藏:0      [点我收藏+]
bubuko.com,布布扣
//代码引自Java设计模式,我自己稍有改动

public class Factory{
    private static Factory factory;
    
    private long wipMoves;

    private Factory(){
        wipMoves=0;
    }

    public static Factory getFactory(){
        synchronized(Factory.class){//这里能不能用this???
             if(factory==null)
              factory=new Factory();
           return factory;
        }
    }
}
bubuko.com,布布扣

Java中,不能在static 方法中使用this:http://www.cnblogs.com/EvanLiu/archive/2013/06/05/3118420.html

 感觉那个例子不是很好哇,http://my.oschina.net/u/866190/blog/205454这个分析还是比较好的

很多人熟知单例模式中有一种写法是使用双重检查锁实现的,但是在网上看到的例子基本上都不正确,有些写是正确,但没有很好解析,造成很多人没有真正理解。其中,典型错误写法是这样的:

bubuko.com,布布扣
 1 public class Resource {
 2 
 3     private static Resource resource ;
 4     
 5     public static Resource getInstance(){
 6         
 7         if(resource == null ){
 8             synchronized (Resource.class) {
 9                 if(resource  == null ){
10                     resource  = new Resource() ;
11                 }
12             }
13             
14         }
15         
16         return resource ;
17     }
18     
19     private Resource(){}
20 
21 }
bubuko.com,布布扣

它基本思路是,首先在没有同步的情况下检查resource是否等于null,如果条件不成立,直接返回resource 。否则,就使用同步再检查resource是否等于null,条件成立才正真初始化resource。这中方式既保证只有一个线程初始化resource,又能做到延时加载。似乎是“鱼和熊掌可兼得“。

上面程序真正的问题是没有同步的情况下读取共享变量resource,并发的情况下对象的状态值有可能是过期无效的。要解决这个问题也很简单,把resource声明为volatile类型。volatile有什么作用?引用《java并发编程实战》的解析:

 

bubuko.com,布布扣
当一个域声明为volatile类型后,编译器与运行时会监视这个变量:它是共享的,而且对它的操作不会与其他的内存操作一起被重排序。
volatile变量不会缓存在寄存器或缓存在对其他处理器隐藏的地方。所以,读一个volatile类型的变量时,总会返回由某一线程所写入的最新值。
bubuko.com,布布扣

读取volatile变量比读取非volatile变量的性能几乎没有差别,不过需要注意的是volatile只能保证内存可见性,并不能保证原子性。

所以嘛,这个是双重检查锁中最好的代码(代码引自维基百科)

bubuko.com,布布扣
 1   public class Singleton {
 2     private static volatile Singleton INSTANCE = null;
 3  
 4     // Private constructor suppresses 
 5     // default public constructor
 6     private Singleton() {}
 7  
 8     //thread safe and performance  promote 
 9     public static  Singleton getInstance() {
10         if(INSTANCE == null){
11              synchronized(Singleton.class){
12                  //when more than two threads run into the first null check same time, to avoid instanced more than one time, it needs to be checked again.
13                  if(INSTANCE == null){ 
14                      INSTANCE = new Singleton();
15                   }
16               } 
17         }
18         return INSTANCE;
19     }
20   }
bubuko.com,布布扣

 维基百科真好,再看看这个:http://zh.wikipedia.org/wiki/%E5%8F%8C%E9%87%8D%E6%A3%80%E6%9F%A5%E9%94%81%E5%AE%9A%E6%A8%A1%E5%BC%8F#Java.E4.B8.AD.E7.9A.84.E4.BD.BF.E7.94.A8

(维基百科,饿汉方式)

bubuko.com,布布扣
  public class Singleton {
    private final static Singleton INSTANCE = new Singleton();
 
    // Private constructor suppresses   
    private Singleton() {}
 
    // default public constructor
    public static Singleton getInstance() {
        return INSTANCE;
    }
  }
bubuko.com,布布扣

http://www.cnblogs.com/techyc/p/3529983.html中说

根据Java Language Specification,JVM本身保证一个类在一个ClassLoader中只会被初始化一次。那么根据classloader的这个机制,我们在类装载时就实例化,保证线程安全。

但是,有些时候,这种创建方法并不灵活。例如实例是依赖参数或者配置文件的,在getInstance()前必须调用某些方法设置它的参数。

http://www.cnblogs.com/techyc/p/3529983.html中也说了单例模式失效的场景

http://blog.csdn.net/haoel/article/details/4028232中说明对失效情况进行了分析

 

Effective Java作者Josh Bloch 提倡的是用枚举

还有其他方法,参看:

http://zh.wikipedia.org/wiki/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F

http://blog.csdn.net/haoel/article/details/4028232

http://www.blogjava.net/kenzhh/archive/2013/03/15/357824.html

 

通常单例模式在Java语言中,有两种构建方式:(维基百科)

  • 懒汉方式(延迟加载)。指全局的单例实例在第一次被使用时构建。
  • 饿汉方式(非延迟加载)。指全局的单例实例在类装载时构建。

双重检查锁定模式首先验证锁定条件(第一次检查),只有通过锁定条件验证才真正的进行加锁逻辑并再次验证条件(第二次检查)。(维基百科)

 

说了这么多,还不知道什么情况下使用单例模式呢,如果让举个例子,怎么说呢

http://blog.csdn.net/csh624366188/article/details/7465505看看这个,虽然不是我想要的结果

登记式单例类 登记式单例类是GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。(http://www.javaarch.net/jiagoushi/557.htm,博主应该是阿里的人,先膜拜一把)“饿汉式单例类及懒汉式单例类均不可继承”这句话不懂唉,还说“java.lang.Runtime 典型的单例模式”

这些下次看这个时再找资料补充吧

单例模式,布布扣,bubuko.com

单例模式

原文:http://www.cnblogs.com/crane-practice/p/3660119.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!