JAVA设计模式:单例模式

/**
 * @ClassName SingleTon
 * @Author 潘忆慈
 * @Computer DELL G7
 * @Date 2018/11/3 9:38
 * @Version 1.0
 * @Discription TODO
 * @注释: 单例设计模式(Singleton Pattern):
 *
 *                      摘要:  保证一个类只有一个实例,并创建一个能访问他的全局访问点
 *
 *                      单例模式三要素:
 *                                      1.单例类只能有一个实例 (需考虑被反射破坏,序列化/反序列化,对象垃圾回收)
 *                                      2.单例类必须自己创建唯一的实例(private修饰)
 *                                      3.单例类必须给所有其他对象提供这一个实例(静态方法getInstance()返回)
 *
 *                       优点:
 *                                      1.提供了唯一的实例受控访问,避免对资源的多重占用
 *                                      2.内存里只有一个实例,减少了内存开销
 *                       缺点:
 *                                      1.单例模式中没有抽象层,因此扩展很是问题
 *                                      2.一定程度上违反了“单一职责原则”
 *			 随笔:
 *                                      如果我们不将这个类控制成单例的结构,应用中就会存在很多一模一样的类实例
 *                                      这会非常浪费系统的内存资源,而且容易导致错误甚至一定会产生错误
 *                                      所以我们单例模式所期待的目标或者说使用它的目的,是为了尽可能的节约内存空间
 *                                      减少无谓的GC消耗,并且使应用可以正常运作。
 *
 *                        如何判断一个类是否要做成单例?
 *                                      最简单的区别就是"这个类在应用中有两个或者两个以上的实例会引起错误,
 *                                      又或者这个类在整个运行时刻中只允许有一种状态"。
 *                        经典应用场景:
 *                                      缓存、日志、配置文件、线程池.....
 *
 *                        单例模式的六种代码实现方式:
 *                                      1.饿汉模式             (简单)
 *                                      2.懒汉模式             (线程不安全)
 *                                      3.同步懒汉模式          (同步方法效率低)
 *                                      4.双重校验锁模式        (可用)
 *                                      5.静态内部类模式        (较为推荐)
 *                                      6.枚举模式             (黄书推荐(Effective JAVA)不常见)
 *
 **/
public class SingleTon {
    public static void main(String[] args) {

        //懒汉模式
        LazyManSingleTon.getInstance();
        //饿汉模式
        HungryManSingleTon.getInstance();
        //同步饿汉模式
        SyLazyManSingleTon.getInstance();
        //双重校验锁模式
        DoubleLockSingleTon.getInstance();
        //静态内部类模式
        StaticSingleTon.getInstance();
        //枚举模式
        //EasySingleton.INSTANCE;

        //测试案例
        TestSingleTon testSingleTon_1 = TestSingleTon.getSingleTon();
        System.out.println(testSingleTon_1.getData());		//打印结果 0
        testSingleTon_1.setData(99);
        System.out.println(testSingleTon_1.getData());		//打印结果99

        TestSingleTon testSingleTon_2 = TestSingleTon.getSingleTon();
        System.out.println(testSingleTon_2.getData());		//打印结果99
    }
}

//———————————————————————饿汉模式————————————————————————
/**
 *  饿汉模式
 *  Lazy 不初始化
 *  多线程 安全
 *
 *  优点: 没有加锁执行效率高,
 *  缺点: 没有Lazy初始化,可能有时候不需要使用,浪费内存
 */
class HungryManSingleTon{

    //静态实例变量,直接初始化
    private static SingleTon instance = new SingleTon();

    //私有化构造器
    private HungryManSingleTon(){}

    //静态public方法,向整个业务提供单例获取方式
    public static SingleTon getInstance(){
        return instance;
    }
}

//———————————————————————懒汉模式————————————————————————
/**
 *  懒汉模式
 *  Lazy 会初始化
 *  多线程 不安全
 *
 *  特点:
 *       能够在调用getInstance()时再创建对象,所以称为懒汉式。不调用不创建,而上文的饿汉模式会直接创建
 *       这种实现最大的问题就是不支持多线程。因为没有加锁同步。
 */
class LazyManSingleTon{

    //静态实例变量, 但不初始化
    private static SingleTon instance;

    //私有化构造器
    private LazyManSingleTon(){}

    //提供全局的单例获取方式
    public static SingleTon getInstance(){
        //判断 instance 是否为空
        if(instance == null){
            //在这个地方 new 对象
            instance = new SingleTon();
        }
        return instance;
    }
}

//—————————————————————同步懒汉模式————————————————————————
/**
 *  同步懒汉模式
 *  Lazy 会初始化
 *  多线程 安全
 *
 *  特点:
 *       使用synchronized来修饰,除第一次使用,后面getInstance()不需要同步;每次同步,效率很低。
 *       效率很低!
 */
class SyLazyManSingleTon{

    //静态实例变量, 但不初始化
    private static SingleTon instance;

    //私有化构造器
    private SyLazyManSingleTon(){}

    //提供全局的单例获取方式
    public static synchronized SingleTon getInstance(){
        //判断 instance 是否为空
        if(instance == null){
            //new一个SingleTon对象
            instance = new SingleTon();
        }
        return instance;
    }
}

//————————————————————双重校验锁模式————————————————————————
/**
 *  双重校验锁
 *  Lazy 会初始化
 *  多线程 安全
 *
 *  特点:
 *       这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
 *       实例变量需要加volatile 关键字保证易变可见性,JDK1.5起才可用
 */
class DoubleLockSingleTon{

    // 静态实例变量,不是初始化,使用volati修饰
    private static volatile SingleTon instance;

    //私有化构造器
    private DoubleLockSingleTon(){}

    //提供全局的单例获取方式
    public static SingleTon getInstance(){
        if(instance == null){
            synchronized (SingleTon.class){
                if(instance == null){
                    instance = new SingleTon();
                }
            }
        }
        return instance;
    }
}

//———————————————————静态内部类模式--———————————————————————
/**
 *  静态内部类模式
 *  Lazy 会初始化
 *  多线程 安全
 *
 *  特点:
 *        同样利用了JVM类加载机制来保证初始化实例对象时只有一个线程,静态内部类SingletonHolder
 *        类只有第一次调用 getInstance 方法时,才会装载从而实例化对象。
 */
class StaticSingleTon{

    private static class SingletonHolder {

        private static final SingleTon INSTANCE = new SingleTon();
    }

    private StaticSingleTon (){}

    public static final SingleTon getInstance() {

        return SingletonHolder.INSTANCE;
    }
}

//———————————————————---枚举模式--———————————————————————
/**
 *  枚举模式
 *  Lazy   不会初始化
 *  多线程 安全
 *
 *  特点:
 *         从Java1.5开始支持enum特性;无偿提供序列化机制,
 *         绝对防止多次实例化,即使在面对复杂的序列化或者反射攻击的时候。
 *
 *         这种方法没有被广泛采用,而且让人生疏
 *         但是! 这是单例模式的最佳实现方法
 */
/*public enum EnumSingleTon{

    //定义一个枚举元素,代表Singleton实例
    INSTANCE;

    public void doSomethingMethod() {

    }
}*/


/**
 * 杨老师的实验案例
 * 懒汉模式
 */
class TestSingleTon{

    private int data;

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    private static TestSingleTon singleTon;

    private TestSingleTon(){}

    public static TestSingleTon getSingleTon(){
        if(singleTon == null){
            singleTon = new TestSingleTon();
        }
        return singleTon;
    }
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值