我是靠谱客的博主 欢呼鞋子,最近开发中收集的这篇文章主要介绍设计模式之创建型模式:单例模式一、设计模式概述二、单例模式概述三、单例模式实现四、单例模式在JDK源码中的应用示例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

设计模式之创建型模式:单例模式

  • 一、设计模式概述
  • 二、单例模式概述
  • 三、单例模式实现
    • 1. 饿汉式实现
    • 2. 懒汉式实现
      • 2.1 多线程不安全的实现
      • 2.2 多线程安全的实现
        • 2.2.1 synchronized实现
        • 2.2.2 双重检查实现
        • 2.2.3 静态内部类实现
    • 3. 枚举实现
  • 四、单例模式在JDK源码中的应用示例

一、设计模式概述

设计模式是基于设计模式原则的基础上,由众多软件开发人员对所遇到的软件工程设计问题所总结的经验,它是某类问题的解决方案,代表了某类问题的最佳实践,它的最终目的是为了提高软件的可维护性,可读性,通用性,可扩展性等

设计模式最经典的书籍就是由“四人组GOF”所编写的【设计模式】,该书将设计模式总结为三种类型,共23种,我后续的设计模式就按照这23种设计模式逐一讲解。

23种设计模式分别如下:

  1. 创建型模式(5种):单例模式,抽象工厂模式,原型模式,建造者模式,工厂模式。
  2. 结构型模式(7种):适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式。
  3. 行为型模式(11种):模板方法模式,命令模式,访问者模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式。

本文讲解创建型模式中的单例模式。

二、单例模式概述

单例设计模式就是保证在整个软件系统中,对某个类只能存在一个对象实例,该对象实例由类提供一个静态方法获取。

单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能

基于单例模式的特点,其应用场景如下:

  • 对于一些重量级的对象(创建时耗时或者耗费资源过多)
  • 需要频繁进行创建和销毁的对象
  • 经常用到的工具类对象
  • 频繁访问数据库或文件的对象

三、单例模式实现

1. 饿汉式实现

所谓饿汉式实现就是指,不论这个类对象是否会用到,在类加载的时候就进行实例化

饿汉式单例模式,直接对静态变量进行实例化,代码实现如下:

class Singleton {
	
	//1. 构造器私有化, 外部能new
	private Singleton() {
		
	}
	
	//2.本类内部直接创建对象实例
	private final static Singleton instance = new Singleton();
	
	//3. 提供一个公有的静态方法,返回实例对象
	public static Singleton getInstance() {
		return instance;
	}
	
}

饿汉式单例模式,将静态变量在静态代码块中进行实例化,代码实现如下:

class Singleton {
	
	//1. 构造器私有化, 外部能new
	private Singleton() {
		
	}
	

	//2.本类内部创建对象实例
	private  static Singleton instance;
	
	static { // 在静态代码块中,创建单例对象
		instance = new Singleton();
	}
	
	//3. 提供一个公有的静态方法,返回实例对象
	public static Singleton getInstance() {
		return instance;
	}
	
}

2. 懒汉式实现

所谓懒汉式实现是指只有用到某个类对象时才会创建,用不到就不会创建,可以减少系统资源浪费。具体实现方法包括多线性不安全和多线程安全两种类型,对应线程不安全的实现只适用于单线程使用。

2.1 多线程不安全的实现

  • 代码实现:
class Singleton {
	private static Singleton instance;
	
	private Singleton() {}
	
	//提供一个静态的公有方法,当使用到该方法时,才去创建 instance
	//即懒汉式
	public static Singleton getInstance() {
		if(instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}
  • 为什么多线程不安全?
    因为在多线性环境下,有可能多个线程同时进入if代码块,这样就会导致多个线程都进行实例化操作,产生不一样的对象

2.2 多线程安全的实现

2.2.1 synchronized实现

代码实现:

class Singleton {
	private static Singleton instance;
	
	private Singleton() {}
	
	//提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
	//即懒汉式
	public static synchronized Singleton getInstance() {
		if(instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}
  • 分析
    因为在获取实例化对象的方法上添加了同步关键字,就可以保证每次只有一个线程进入该方法,保证了多线程必然得到的是同一个实例化对象。但是这种实现方法的缺点是造成效率降低,因为每一个线程访问都要进行同步,但理论上只要一个线程完成实例化后,其它线程就不会再存在得到不同对象的问题了,因此可以不需要同步操作了。
    为了解决该实现方法造成的效率低的问题,提出双重检查实现方法,该方法既可以保证线程安全,又可以尽可能的少的使用同步代码块。

2.2.2 双重检查实现

  • 代码实现
class Singleton {
	private static volatile Singleton instance;//必须使用volatile关键字,防止指令重排
	
	private Singleton() {}
	
	//提供一个静态的公有方法,加入双重检查代码,解决线程安全问题, 同时解决懒加载问题
	//同时保证了效率, 推荐使用
	
	public static Singleton getInstance() {
		if(instance == null) {//如果尚未创建对象,可能多个线程进入下面的代码块
			synchronized (Singleton.class) {//保证一次只能有一个线程进入其代码块
				if(instance == null) {//假设一个线程已经实例化了对象,如果再有线程进来,就会发现instance不为null,就不会再实例化对象
					instance = new Singleton();
				}
			}
			
		}
		return instance;
	}
}

2.2.3 静态内部类实现

  • 代码实现
class Singleton {
	//构造器私有化
	private Singleton() {}
	
	//写一个静态内部类,该类中有一个静态属性 Singleton
	private static class SingletonInstance {
		private static final Singleton INSTANCE = new Singleton(); 
	}
	
	//提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
	
	public static Singleton getInstance() {
		
		return SingletonInstance.INSTANCE;
	}
}
  • 分析
    静态内部类在外面的类加载的时候不会初始化,只有使用到内部类时才会由jvm类加载器加载,而JVM可以保证线程的安全性,因此实现了线程安全,并且很明显实现了懒加载。

3. 枚举实现

  • 代码实现
enum Singleton {
	INSTANCE; //属性
}
  • 分析
    枚举实现单例模式是官方推荐的一种方法,枚举实现非常简单,并且基于JVM保证了线程安全。

四、单例模式在JDK源码中的应用示例

JDK中Runtime类就是实现了饿汉式单例模式,部分源码如下:
在这里插入图片描述

最后

以上就是欢呼鞋子为你收集整理的设计模式之创建型模式:单例模式一、设计模式概述二、单例模式概述三、单例模式实现四、单例模式在JDK源码中的应用示例的全部内容,希望文章能够帮你解决设计模式之创建型模式:单例模式一、设计模式概述二、单例模式概述三、单例模式实现四、单例模式在JDK源码中的应用示例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部