设计模式之单例模式

之前浅显的了解单例模式,只知其果不知其因,被面试官疯狂教做人,决定重写这篇文章,之前写的实在是简单了,寄希望于下次面试能够在设计模式秀一波。

首先单例模式是如何实现单例的,这是十分重要的,那就是构造函数私有化,这个操作十分巧妙,使得外部无法创建该对象,保证了单例的这个“单”字,即只有一个实例。其他对象只能通过单例对象的公共方法获得单例对象的实例。

public class Main {

    private Main()
    {
        System.out.println("Main 构造函数");
    }


    public static void main(String[] args) {
         Main main=new Main();

    }
}
运行结果:
Main 构造函数

public   class test3 {
    public static void main(String[]args)
    {
       Main main=new Main();//报错

    }
}

在了解了单例模式的含义后,我们再来看单例模式的几种写法。

单例模式
应用场景:有些对象只需要一个就足够了
作用:整个应用程序的某个实例有且只有一个
类型:饿汉模式、懒汉模式、线程安全的懒汉模式、双锁校验模式

饿汉模式

特点:

  • .加载类比较慢,运行时获取对象速度比较快
  • 线程安全
public class Singleton{
        //1.构造方法私有化,不许外部直接创建对象
        private Singleton()
        {
        }

         //2.创建类的唯一实例
        static private Singleton instance=new Singleton();

        //3.提供获取实例方法
        public static Singleton getInstance()
        {
                return instance;
        }
}

懒汉模式

特点:

  • .加载类比较快,运行时获取对象速度比较慢
  • 线程不安全
public class Singleton{
    //1.构造方法私有化,不允许外部直接创建对象

     private Singleton()
        {
        }

        //2.声明类的唯一实例
        static private Singleton instance;

        //3.提供获取实例的方法
        public static Singleton getInstance()
        {
                if(instance==null)
                {
                        instance=new Singleton();
                }
                return instance;
        }
}

线程安全的懒汉模式

  • 线程安全,但是由于锁住了整个方法,速度相对来说是很慢的
public class Singleton{
    //1.构造方法私有化,不允许外部直接创建对象

     private Singleton()
        {
        }

        //2.声明类的唯一实例
        static private Singleton instance;

        //3.提供获取实例的方法
        public static synchronized Singleton getInstance()
        {
                if(instance==null)
                {
                        instance=new Singleton();
                }
                return instance;
        }
}

双锁校验

public class Singleton {
    private volatile static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

我们需要关注的重点有两个:

  • 为什么有两次判断空

此模式是为了解决线程安全问题,那么我们将视多线程为常态,我们假设只有只有一次判断为空,那么可能会有两个线程同时进入if语句中,这两个线程都会创建实例,只不过一个先创建一个后创建。所以需要再一次判断

if (uniqueInstance == null) {
    synchronized (Singleton.class) {
        uniqueInstance = new Singleton();
    }
}
  • 为什么设置返回变量uniqueInstance为volatile类型

大家都知道JMM有一个指令重排序的概念,而uniqueInstance = new Singleton()这个语句并不具有原子性,分为
- 为 uniqueInstance 分配内存空间
- 初始化 uniqueInstance
- 将 uniqueInstance 指向分配的内存地址

一旦第三步指令重排序到前面,那么得到的对象可能会是个空对象,而volatile修饰的变量具有禁止指令重排序的功能,所以避免了这种情况。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值