单件(例)模式


定义:确保一个类只有一个实例,并提供一个全局访问点。

要点:

  1. 单件模式确保程序中一个类最多只有一个实例。
  2. 单件模式也提供访问这个实例的全局点。
  3. 在java中实现单件模式需要私有的构造器、一个静态方法和一个静态变量。
  4. 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程的问题(我们必须认定所有的程序都是多线程的)。
  5. JDK1.4版本及之前,双重检查加锁实现会失效。
  6. 如果使用多个类加载器,可能导致单件失效而产生多个实例。每个类加载器定义了一个命名空间,如果有两个以上,不同的类加载器可能会加载同一个类,从而产生多个单件并存的怪异现象。
  7. 如果使用jvm1.2或之前的版本,你必须建立单件注册表,以免垃圾收集器将单件回收。
  8. 通俗讲的饿汉式和懒汉式,指的就是单件的急切实例化和延迟实例化。
  9. 全局变量比单件模式差,全局变量可能造成命名空间的污染,不能确保只有一个实例。
单件实现方式一:非线程安全
package com.example.pattern.singleton;

/**
 * <p>
 * <code>Singleton</code>
 * </p>
 * Description: 线程不安全,在多线程环境下可能创建多个实例
 *
 * @author Mcchu
 * @date 2018/1/17 14:27
 */
public class Singleton {

    /**
     * 单件变量
     */
    private static Singleton uniqueInstance;

    /**
     * 声明私有构造器
     */
    private Singleton(){ }

    /**
     * 外部调用方法
     * @return uniqueInstance
     */
    public static Singleton getInstance(){
        if ( uniqueInstance==null ){
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

单件模式实现方式二:线程安全,性能低
package com.example.pattern.singleton;

/**
 * <p>
 * <code>SingletonThreadSafeRepeat</code>
 * </p>
 * Description: 线程安全,但是降低了性能,因为只有第一次创建单件时才需要做线程控制
 *
 * @author Mcchu
 * @date 2018/1/17 15:13
 */
public class SingletonThreadSafeRepeat {

    /**
     * 单件变量
     */
    private static SingletonThreadSafeRepeat uniqueInstance;

    /**
     * 私有构造器
     */
    private SingletonThreadSafeRepeat(){};

    /**
     * 对外公开
     * @return uniqueInstance
     */
    public static synchronized SingletonThreadSafeRepeat getInstance(){
        if ( uniqueInstance==null ){
            uniqueInstance = new SingletonThreadSafeRepeat();
        }
        return uniqueInstance;
    }
}

单件模式实现方式三:饿汉式-急切创建
package com.example.pattern.singleton;

/**
 * <p>
 * <code>SingletonThreadSafe</code>
 * </p>
 * Description: 线程安全->依赖jvm在加载这个类时马上创建此唯一的单件实例
 *
 * @author Mcchu
 * @date 2018/1/17 14:47
 */
public class SingletonThreadSafe {

    /**
     * “急切”创建实例(又称饿汉式),
     */
    private static SingletonThreadSafe uniqueInstance = new SingletonThreadSafe();

    /**
     * 声明私有构造器
     */
    private SingletonThreadSafe(){}

    /**
     * 直接使用上面创建的实例
     * @return uniqueInstance
     */
    public static SingletonThreadSafe getInstance(){
        return uniqueInstance;
    }
}

单件模式实现方式四:双重检查加锁

package com.example.pattern.singleton;

/**
 * <p>
 * <code>SingletonDoubleLockThreadSafe</code>
 * </p>
 * Description: 双重加锁->double-checked locking,线程安全
 *
 * @author Mcchu
 * @date 2018/1/17 14:49
 */
public class SingletonDoubleLockThreadSafe {

    /**
     * JDK1.4及更早版本,JCM对于volatile关键字的实现会导致双重检查加锁失效,所以不要用此方法实现
     */
    private volatile static SingletonDoubleLockThreadSafe uniqueInstance;

    /**
     * 私有构造器
     */
    private SingletonDoubleLockThreadSafe(){};

    public static SingletonDoubleLockThreadSafe getInstance(){
        if ( uniqueInstance==null ){
            // 注意,这里是在不存在时进入同步区块
            synchronized ( SingletonDoubleLockThreadSafe.class ){
                if ( uniqueInstance==null ){
                    uniqueInstance = new SingletonDoubleLockThreadSafe();
                }
            }
        }
        return uniqueInstance;
    }
}



附:
Head First设计模式第五章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值