设计模式--单例模式

关于设计模式

设计模式是解决问题的方案,学习现有的设计模式可以做到经验复用。

我的理解的话就是对于java语言的面向对象这一特性的的产物,在不同的环境,需求下对象管理的经验总结;

单例模式

单例模式是最基本与最基础的一种设计模式,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

其核心思想是:一个类只有一个实例,并提供该实例的全局访问点

实现方式:

  • 使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。

  • 私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。

最关键的就是构造函数的私有的,也就是不提供对外实例化函数;

具体实现

package com.test;

/**
 * @author: yzp
 * @Date: 2019/11/2 12:16
 * @Description:  单例模式
 */
public class Singleton {
    /**
     *     创建一个 Singleton 对象
     */
    private static Singleton singleton = new Singleton();

    /**
     * 私有化构造函数,防止被实例化
     */
    private Singleton() {
    }


    /**
     * 提供一个对外的获取此对象的方法
     */
    public static Singleton getInstance(){
        return singleton;
    }
}

以上就是一个最基本的单例模式实现类,参照的是菜鸟教程

测试

既然我们已经遵守单例模式的规范定义了一个类,那么下面来测试一下是否真正的实现了单例模式:

package test;

import com.test.Singleton;

/**
 * @author: yzp
 * @Date: 2019/11/2 12:29
 * @Description:
 */
public class SingletonTest {

    public static void main(String[] args) {

         // 获取一个 Singleton 对象 singleton1
        Singleton singleton1 = Singleton.getInstance();

        // 获取一个 Singleton 对象 singleton2
        Singleton singleton2 = Singleton.getInstance();

        // 比较 hashCode
        if (singleton1 == singleton2){

            System.out.println("singleton1 hashCode = " + singleton1.hashCode() );
            System.out.println("singleton2 hashCode = " + singleton2.hashCode() );
        }


        // 比较实际对象
        if (singleton1.equals(singleton2)){

            System.out.println("单例模式");
        }

    }
}

控制台输出:
在这里插入图片描述
无论是两次获取对象的 hashCode 比较还是 equals 比较,都是 一致的;说明两次获取的对象都是同一个对象,只生成了一个对象;

单例模式的实现有多种方式:

单例模式 -懒汉模式(线程不安全)

public class Singleton {

    private static Singleton instance;
    
    private Singleton (){}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。

单例模式 -懒汉模式(线程安全)

public class Singleton {

    private static Singleton instance;

    private Singleton (){}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

在获取实例对象的方法上添加了synchronized 关键字,保证了在多线程下的单例;

单例模式-饿汉模式(线程安全)

此种模式就是我上面举例的,在类装载的时候就进行初始化,没有加锁,执行效率会提高,但是容易产生垃圾对象,当外部调用类中其他静态方法时也会生成对象(虽然很少),造成内存浪费;

单例模式-静态内部类

public class Singleton {
        private static class SingletonHolder {

            private static final Singleton INSTANCE = new Singleton();
        }
        private Singleton (){
        }

        public static final Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }

}

此种方式创建单例,将对象的创建放置在静态代码块之内,只有获取当前对象的时候才会创建对象,不会对使用类内其他静态方法造成影响;也不会造成内存浪费;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值