单子设计模式(Singleton Pattern)

GOF设计模式
Singleton Pattern
单子设计模式

• 有时候,我们需要实现这样的功能:那就是在整个应用中,只有一个实例存在。比如,在PowerPoint中,只能出现一个帮助窗口。如果将这个帮助窗口当作一个类,这就意味着它只能有一个实例。我们在以后会使用JDBC连接数据库程序,也可以使用该模式。

• 所谓类的单子(Singleton)设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类提供了一个取得其对象实例的方法。

单子模式第一种写法
• 步骤:
• 1.首先必须将类的构造方法的访问权限设置为private,这样,就不能用new 操作符在类的外部产生类的对象了。
• 2.在类的内部定义并产生那个唯一的对象,并限制其访问权限为private。
• 3.提供给外部一个public类型的静态方法,可以获得该唯一对象。
• 缺陷:在多线程不能正常工作。

public class Animal1 {
    private Animal1(){

    }
    private static Animal1 animal1;
    public static Animal1 getInstance1(){
        if(animal1==null){
            animal1=new Animal1();
        }
        return animal1;
    }
}
public class Test1 {
    public static void main(String[] args) {
        Animal1 a=Animal1.getInstance1();
        Animal1 b=Animal1.getInstance1();
        System.out.println(a);
        System.out.println(b);
    }
}
单子模式第二种写法
• 这种写法能够在多线程中很好的工作,效率很低,99%情况下不需要同步。

(加了synchronized用来同步)

public class Animal2 {
    private Animal2(){

    }
    private static Animal2 animal2;
    public static synchronized Animal2 getInstance2(){
        if(animal2==null){
            animal2=new Animal2();
        }
        return animal2;
    }
}

public class Test2 {
    public static void main(String[] args) {
        Animal2 a=Animal2.getInstance2();
        Animal2 b=Animal2.getInstance2();
        System.out.println(a);
        System.out.println(b);
    }
}

单子模式第三种写法
• 应用内部类也能实现单子模式,而且是比较安全的单子模式。
• 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程。
• 该种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,这种方式相就显得很合理。

(运用内部类)

public class Animal3 {
    private Animal3(){

    }
    private static class SingletonHolder{
        private static final Animal3 instance=new Animal3();
    }
    public static Animal3 getInstance3(){
        return SingletonHolder.instance;
    }
}

public class Test3 {
    public static void main(String[] args) {
        Animal3 a=Animal3.getInstance3();
        Animal3 b=Animal3.getInstance3();
        System.out.println(a);
        System.out.println(b);
    }
}

单子模式的第四种写法
• 这是第二种方式的升级版,俗称双重检查锁定版。

(加了volatile和synchronized)

public class Animal4 {
    private Animal4(){

    }
    private static volatile Animal4 animal4;
    public static Animal4 getInstance4(){
        if(animal4==null){
            synchronized(Animal4.class){
                animal4=new Animal4();
            }
        }
        return animal4;
    }

}

public class Test4 {
    public static void main(String[] args) {
        Animal4 a=Animal4.getInstance4();
        Animal4 b=Animal4.getInstance4();
        System.out.println(a);
        System.out.println(b);
    }
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值