单例设计模式笔记

单例模式类似计划生育,其保证类仅有一个实例,且对外提供访问该实例的接口。
所有类都有构造器,若不显示定义,则系统提供默认的构造器;若显示定义,则默认的构造器失效。
使用常规代码实现单例会导致代码臃肿,后期debug和修改时工作量加大。

public class Singleton {

    private static Singleton obj;   //obj设为static

    private Singleton() {   //构造器设为private

    }

    public static Singleton getInstance() { //给外部提供一个单例接口
        if (obj == null)
            obj = new Singleton();
        return obj;
    }
}

实用类:仅仅只是静态方法和静态属性的集合,没有实例对象,如Math类。
为保证单例模式在多线程下的安全性,有两种解决方案,饿汉式和懒汉式(形象的比喻)。

饿汉式(线程安全,代码简洁,空间效率低):

public class Singleton {

    private static Singleton obj = new Singleton(); //obj设为static

    private Singleton() {   //构造器设为private

    }

    public static Singleton getInstance() { //给外部提供一个单例接口
        return obj;
    }
}

懒汉式(延迟实例对象创建时间,只有在需要时才创建):线程等待时有一定的时间开销。

直接对接口加锁:效率低,保证线程安全。

public class Singleton {

    private static Singleton obj;   //obj设为static

    private Singleton() {   //构造器设为private

    }

    public synchronized static Singleton getInstance() {    //给外部提供一个单例接口
        if (obj == null)
            obj = new Singleton();
        return obj;
    }
}

双重检测:效率高,保证线程安全

public class Singleton {

    private static Singleton obj;   //obj设为static
    private static Object lock = new Object();  //创建一个对象,该对象作为锁使用

    private Singleton() {   //构造器设为private

    }

    public static Singleton getInstance() { //给外部提供一个单例接口
        if (obj == null) {  //只有对象还未创建时,才进行加锁,否则直接返回对象,无需加锁
            synchronized (lock) {
                if (obj == null)
                    obj = new Singleton();
            }
        }
        return obj;
    }
}

JDK5之后实现单例的最佳方法是枚举单个元素。
枚举类似类,一个枚举可以拥有成员变量,成员方法,构造方法。

enum Type {
    A,B,C;
    //field and method...
}

上面的枚举类型等价:

class Type extends Enum {
    public static final Type A;
    public static final Type B;
    public static final Type C;

    //field and method...
}

注意这个过程是由javac编译器自动转换的,手动书写上述代码不能通过编译。
枚举类中的构造方法默认是私有的,因此可以利用这个特性实现单例。

class User {

    //...

}

enum SingletonUser{
    INSTANCE;

    private User user;
    SingletonUser() {
        user = new User();
    }

    public User getInstance() {
        return user;
    }
}

我们可以通过SingletonUser.INSTANCE.getInstance()方法获取User类的唯一实例user。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值