java基础设计模式1——单例模式

概念:在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。

单例模式从实现上可以分为饿汉式单例懒汉式单例两种,前者天生就是线程安全的,后者则需要考虑线程安全性,常见的线程安全的懒汉式单例的实现有内部类式双重检查式两种。下面给出单例模式几种常见的形式:

(1)饿汉式单例

单例模式的核心有两点:

  • 私有化的构造方法
  • 公有化的静态的getInstance方法
/**
 * 恶汉式单例模式
 * @author Xia
 */
public class Singleton {
    //指向自己实例的私有静态引用,主动创建
    private static Singleton instance = new Singleton();
    //私有的构造方法
    private Singleton(){}
    
    //以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton getInstance(){
        return instance;
    }
}

(2)懒汉式单例

懒汉式单例的核心点:

  • 私有化的构造方法
  • 只有在需要的时候才被创建实例

因此对于多线程而言,无法保证线程安全。

为什么无法保证线程安全呢?

我们假设有多个线程1,线程2都需要使用这个单例对象。而恰巧,线程1在判断完instance==null后突然交换了cpu的使用权,变为线程2执行,由于instance仍然为null,那么线程2中就会创建这个Singleton的单例对象。之后线程1拿回cpu的使用权,而正好线程1之前暂停的位置就是判断instance是否为null之后,创建对象之前。这样线程1又会创建一个新的Singleton对象。

/**
 * 懒汉式单例模式
 * @author Xia
 */
public class Singleton2 {
    
    //指向自己实例的私有静态引用
    private static Singleton2 instance ;
    
    //私有的构造方法
    private Singleton2(){}
    
    //以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton2 getInstance(){
        // 被动创建,在真正需要使用时才去创建
        if (instance == null) {
            instance = new Singleton2();
        }
        return instance;
    }
}

(3)线程安全的懒汉式单例——双重检查方式

上面我们提到,懒汉式的单例模式因为其创建是在需要的时候才new出来,中间可能会被打断,因此,需要用Synchronized关键字将对象锁定。

/**
 * 线程安全的懒汉式单例模式
 * @author Xia
 */
public class Singleton3 {
    
    //指向自己实例的私有静态引用
    private static Singleton3 instance ;
    
    //私有的构造方法
    private Singleton3(){}
    
    //以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton3 getInstance(){
        // 第一次检查
        if (instance == null) {
            //锁定该类对象
            synchronized (Singleton3.class) {
                //第二次检查
                if (instance == null) {
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }
}

猜你喜欢

转载自www.cnblogs.com/xiaxj/p/9786536.html