您的位置:首页 > 其它

单列设计模式几种写法的比较

2017-07-15 17:33 218 查看
单例模式有两种写法,懒汉式和饿汉式

1.饿汉式:在程序启动或单列模式类被加载的时候,单例模式实例就已经被创建。

2.懒汉式:当程序第一次访问单例模式实例时才进行创建。懒汉式实现了延迟加载的功能。

选择:当单例模式在系统中经常被用到时,饿汉式是一个不错的选择。但如果单例模式在系统中很少使用或者几乎不会用到,那么可以选择懒汉式。

好了,写代码吧。
饿汉式代码

public Simple(){
//生成静态实例对象
private static Single s=new Single();
//私有化空构造方法,使其不能在外面new
private Single(){}
//生成公有的供外界访问的方法
public static Simple getSimple(){
return s;
}
}

上面的饿汉式在类一加载的时候,实例对象就已生成,造成资源的浪费。饿汉式优化代码实现延缓加载

public class Single{

//使用内部类,在调用时才加载,实现了延缓加载
private static class SingleHolder {
//生成静态实例对象
private static Single s=new Single();
}

//私有化空构造方法,使其不能在外面new
private Single(){}
//生成公有的供外界访问的方法
public static Single getSimple(){
return SingleHolder.s;
}
}

懒汉式代码

class Single{
private static Single s = null;
private Single(){}
public static Single getInstance() {
if (s == null){
  s = new Single();
}
return s;
  }
}
但是这种方法对于多线程来说不安全,要对生成对象的部分进行加锁,加锁分为两种,一种是在方法上加锁,一种是在代码块上加锁。

先用第一种在方法上加锁

class Single{
private static Single s = null;
private Single(){}
public static synchronized Single getInstance() {
if (s == null){
  s = new Single();
}
return s;
  }
}
这一种可以解决线程不安全的问题,但是不是最好的,因为在第一次生成对象之后,以后每次访问都需要进行锁的判断,效率上会有影响。

在用第二种在代码块上加锁

class Single{
private static Single s = null;
private Single(){}
public static Single getInstance() {
if (s == null){
synchronized(Single.class) {
if(s == null) {
        s = new Single();
}
}
}
return s;
  }
}
在代码块里加了锁,还双重判断,这个是有必要的。因为加入有两个线程同时运行到第一个if判断的地方,判断都为空,一个线程先进去生成一个实例,第二个线程也进去,如果没有第二个if判断,就会也new出一个实例,所以用两个if判断是有必要的。还有一点是这个锁的对象时该类的字节码对象,因为这个方法是静态方法,被放在静态方法区里面了,用类的字节码,能保证对不同线程是同一个对象。懒汉模式里最后一种写法比较好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: