1 初识单例模式:
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点
结构:
参考实现:
public class Singleton { //饿汉式 线程安全下 双重检查机制 两个判null 一个synchronized ; //好处在于 线程安全 并 减少多次同步下进行判断所浪费的时间 /** * 对保存实例的变量添加volatile的修饰 这样当一个线程修改后 别的线程能立马感知到 线程之间共享 volatile这个内存空间 并只有在jdk1.5之后才能使用 */ private volatile static Singleton instance = null; private Singleton(){ } public static Singleton getInstance(){ //先检查实例是否存在,如果不存在才进入下面的同步块 if(instance == null){ //同步块,线程安全的创建实例 synchronized(Singleton.class){ //再次检查实例是否存在,如果不存在才真的创建实例 if(instance == null){ instance = new Singleton(); } } } return instance; } }
2 体会单例模式:
场景问题: 读取配置文件的内容(配置文件内容是固定的,在系统中,得到配置文件的实例类仅仅有一个即可)
不用模式的解决方案: 每次都要new对象 并从配置文件中加载, new出多少个对象就加载多少次;
使用模式的解决方案: 将类设计成静态类,那么对象就一个,加载仅仅加载一次配置文件
package cn.javass.dp.singleton.example4; import java.io.*; import java.util.*; /** * 读取应用配置文件,单例实现 */ public class AppConfig { /** * 定义一个变量来存储创建好的类实例,直接在这里创建类实例,只会创建一次 */ private static AppConfig instance = new AppConfig(); /** * 定义一个方法来为客户端提供AppConfig类的实例 * @return 一个AppConfig的实例 */ public static AppConfig getInstance(){ return instance; } /** * 用来存放配置文件中参数A的值 */ private String parameterA; /** * 用来存放配置文件中参数B的值 */ private String parameterB; public String getParameterA() { return parameterA; } public String getParameterB() { return parameterB; } /** * 私有化构造方法 */ private AppConfig(){ //调用读取配置文件的方法 readConfig(); } /** * 读取配置文件,把配置文件中的内容读出来设置到属性上 */ private void readConfig(){ System.out.println("开始咯"); Properties p = new Properties(); InputStream in = AppConfig.class.getResourceAsStream("AppConfig.properties"); try { p.load(in); //把配置文件中的内容读出来设置到属性上 this.parameterA = p.getProperty("paramA"); this.parameterB = p.getProperty("paramB"); } catch (IOException e) { System.out.println("装载配置文件出错了,具体堆栈信息如下:"); e.printStackTrace(); } } } client: public class Client { public static void main(String[] args) { //创建读取应用配置的对象 for(int i=0; i<3; i++){ AppConfig config = AppConfig.getInstance(); String paramA = config.getParameterA(); String paramB = config.getParameterB(); System.out.println("paramA="+paramA+",paramB="+paramB); } } }
3 理解单例模式:
单例模式命名: 建议方法命名为: getInstance()
单例模式:
懒汉式:以时间换取空间(每次都执行if判定,如果有实例,则不new 否则new)
饿汉式:以空间换取时间(直接new出对象来,占用空间)
延迟加载:最开始不加载,直到马上要使用到时才加载。
缓存思想:将经常用到的数据放在内存中,需要用的时候去内存获取(空间换时间)
java中缓存的基本实现:
/** * Java中缓存的基本实现示例 */ public class JavaCache { /** * 缓存数据的容器,定义成Map是方便访问,直接根据Key就可以获取Value了 * key选用String是为了简单,方便演示 */ private Map<String,Object> map = new HashMap<String,Object>(); /** * 从缓存中获取值 * @param key 设置时候的key值 * @return key对应的Value值 */ public Object getValue(String key){ //先从缓存里面取值 Object obj = map.get(key); //判断缓存里面是否有值 if(obj == null){ //如果没有,那么就去获取相应的数据,比如读取数据库或者文件 //这里只是演示,所以直接写个假的值 obj = key+",value"; //把获取的值设置回到缓存里面 map.put(key, obj); } //如果有值了,就直接返回使用 return obj; } }
利用缓存实现单例模式:
public class cacheSingleton { private static cacheSingleton instance; private cacheSingleton(){} public static Map cacheMap = new HashMap(); private static String key = "key1"; public static cacheSingleton getInStance(){ instance = (cacheSingleton) cacheMap.get(key); if(instance == null){ instance = new cacheSingleton(); cacheMap.put(key, instance); } return instance; } }
单例模式优缺点:
懒汉式在多线程下是线程不安全的
但是饿汉式能够保证线程安全,JVM会保证只会装载一次
懒汉式多线程安全,只需在getInstance(){}内new 实例时 增加synchronized即可。
代码写法见文章最开头
java中一种更好的单例实现方式:(Lazy initialization holder class模式)
package cn.javass.dp.singleton.example11; /** * 0 如下写法好处: * 1 实现延迟加载 * 2 实现线程安全 * @author zm * */ public class Singleton { /** * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系, * 而且只有被调用到才会装载,从而实现了延迟加载 */ private static class SingletonHolder{ /** * 静态初始化器,由JVM来保证线程安全 */ private static Singleton instance = new Singleton(); } /** * 私有化构造方法 */ private Singleton(){ } public static Singleton getInstance(){ return SingletonHolder.instance; } }
单例和枚举: 单元素的枚举类型已经成为实现Singleton的最佳方法
/** * 使用枚举来实现单例模式的示例 */ public enum Singleton { /** * 定义一个枚举的元素,它就代表了Singleton的一个实例 */ uniqueInstance; /** * 示意方法,单例可以有自己的操作 */ public void singletonOperation(){ //功能处理 } }
4 思考单例模式:
本质: 控制实例数目
何时选用: 大多应用在配置文件获取上吧
5 单例模式 扩展为3个写法:
package cn.javass.dp.singleton.example9; import java.util.*; /** * 简单演示如何扩展单例模式,控制实例数目为3个 * * 1 使用map * 2 使用单例 * 3 设置单例个数,然后将每次生成的对象放在map中 */ public class OneExtend { /** * 定义一个缺省的key值的前缀 */ private final static String DEFAULT_PREKEY = "Cache"; /** * 缓存实例的容器 */ private static Map<String,OneExtend> map = new HashMap<String,OneExtend>(); /** * 用来记录当前正在使用第几个实例,到了控制的最大数目,就返回从1开始 */ private static int num = 1; /** * 定义控制实例的最大数目 */ private final static int NUM_MAX = 3; private OneExtend(){} public static OneExtend getInstance(){ String key = DEFAULT_PREKEY+num; OneExtend oneExtend = map.get(key); if(oneExtend==null){ oneExtend = new OneExtend(); map.put(key, oneExtend); } //把当前实例的序号加1 num++; if(num > NUM_MAX){ //如果实例的序号已经达到最大数目了,那就重复从1开始获取 num = 1; } return oneExtend; } public static void main(String[] args) { OneExtend t1 = getInstance(); OneExtend t2 = getInstance(); OneExtend t3 = getInstance(); OneExtend t4 = getInstance(); OneExtend t5 = getInstance(); OneExtend t6 = getInstance(); System.out.println("t1=="+t1); System.out.println("t2=="+t2); System.out.println("t3=="+t3); System.out.println("t4=="+t4); System.out.println("t5=="+t5); System.out.println("t6=="+t6); } }
6 单例模式脑图:
相关推荐
单例模式是软件设计模式中的一种经典模式,它保证了类在任何情况下都只有一个实例存在。这个模式在很多场景下非常有用,例如控制全局资源、管理配置信息等。本文将详细探讨单例模式的懒汉式实现,并结合源码进行解析...
设计模式是软件工程中的一种最佳实践,用于解决在不同场景下重复出现的问题。...通过阅读提供的"iOS 设计模式——单例"相关资料,可以深入理解在iOS开发环境中如何有效利用单例模式来优化代码结构和提高程序性能。
C++设计模式——单例模式-附件资源
单例的5中实现及反射和反序列化破解单例。
【Java设计模式——单例模式】 单例模式是一种常见的软件设计模式,它的核心思想是确保在应用程序的整个生命周期中,某个类只有一个实例存在。这种模式主要用于控制类的实例化过程,减少系统资源的消耗,提高系统...
单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制共享资源、管理系统级别的服务或者简化对象间的交互。单例模式的核心在于...
本次将聚焦于一种较为简单的模式——单例模式。 #### 单例模式概述 单例模式是一种创建型模式,它的核心在于确保某个类只有一个实例,并提供一个全局可访问的访问点。这种模式非常实用,尤其是在需要频繁地创建和...
单例模式是软件设计模式中的一种经典模式,其主要目的是控制类的实例化过程,确保在任何情况下,一个类只有一个实例存在。这种模式通常用于管理共享资源或者全局配置,例如数据库连接池、线程池、日志服务等。在Java...
内容概要:本文档介绍了三个经典的软件设计模式——单例模式(Singleton Pattern)、工厂模式(Factory Pattern)以及观察者模式(Observer Pattern)的具体实现,并给出了带有详细注释的C++代码范例。对每个设计模式都有...
本次我们将深入探讨两种设计模式——单例模式和装饰模式,它们在Java编程中都有着广泛的应用。 首先,让我们来理解“单例模式”。单例模式是一种创建型设计模式,其核心思想是保证一个类只有一个实例,并提供一个...
**设计模式——单例模式** 单例模式是一种广泛应用于软件设计中的创建型设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于控制共享资源的访问,比如线程安全的数据库连接池...
1)程序功能:单例模式设计Memcache和Redis操作类,采用PHP编写。 2)程序详解地址:http://blog.csdn.net/clevercode/article/details/46410055。 3)原创作品,出自"CleverCode的博客",分类为《设计模式之PHP项目...
策略模式和单例模式是软件设计中两种非常重要的设计模式,它们在实际开发中有着广泛的应用。在这篇文章中,我们将深入探讨这两种模式的核心概念、实现方式以及如何在实际项目中运用。 策略模式是一种行为设计模式,...
### Java设计模式——单例模式详解 #### 一、单例模式概述 单例模式是设计模式中的一个重要组成部分,属于创建型模式之一。其主要作用是确保某个类仅有一个实例存在,并提供一个全局访问该实例的方法。这在很多场景...
单例模式是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在iOS应用开发中,单例模式被广泛用于管理共享资源、实现全局设置、提供网络请求管理器等场景。让我们深入探讨一下单例模式在iOS...
单例模式是设计模式中最常见也最简单的一种设计模式,保证了在程序中只有一个实例存在并且能全局的访问到。比如在Android实际APP 开发中用到的 账号信息对象管理, 数据库对象(SQLiteOpenHelper)等都会用到单例...