| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 单例模式(对象私有化) -> 正文阅读 |
|
[Java知识库]单例模式(对象私有化) |
单例模式(对象私有化)目录 单例模式(Singleton Pattern)是Java中最简单的设计模式之?。这种类型的设计模式属于创建型模式,它提供了 ?种创建对象的最佳?式。这种模式涉及到?个单?的类,该类负责创建??的对象,同时确保只有单个对象被创建。这个类提供了?种访问其唯?的对象的?式,可以直接访问,不需要实例化该类的对象。 注意: 1.单例类只能有?个实例。 2.单例类必须??创建??的唯?实例。 3.单例类必须给所有其他对象提供这?实例。 1.介绍意图:保证?个类仅有?个实例,并提供?个访问它的全局访问点。 主要解决:?个全局使?的类频繁地创建与销毁。 何时使?:当你想控制实例数?,节省系统资源的时候。 如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。 关键代码:构造函数是私有的。 应?实例:1.多个进程或线程同时操作?个?件,所以所有?件的处理必须通过唯?的实例进?。 2.?些设备管理器常常设计为单例模式,?如?个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同?个?件。 优点:1.在内存?只有?个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。 2.避免对资源的多重占?(?如写?件操作)。 缺点:没有接?,不能继承,与单?职责原则冲突,?个类应该只关?内部逻辑,?不关?外?怎么样来实例化。 使?场景:1.要求?产唯?序列号。 2.WEB中的计数器,不?每次刷新都在数据库?加?次,?单例先缓存起来。 3.创建的?个对象需要消耗的资源过多,?如I/O与数据库的连接等。 2.实现我们将创建?个SingleObject类。SingleObject类有它的私有构造?法和本身的?个静态实例。 SingleObject类提供了?个静态?法,供外界获取它的静态实例。 3 单例模式实现?式3.1 饿汉式提前将对象准备好,加载到内存中 3.1.1 饿汉式介绍 是否Lazy初始化:否 (提前准备好对象) 是否多线程安全:是 (饿汉式只有一个实例,没有多线程) 描述:这种?式?较常?,但容易产?垃圾对象。 (可能创建出来的对象一直没有用) 优点:没有加锁,执?效率会提?。 缺点:类加载时就初始化,浪费内存。 它基于classloader机制避免了多线程的同步问题,不过instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中?多数都是调?getInstance()?法, 但是也不能确定有其他的?式(或者其他的静态?法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。 3.1.2 饿汉式案例 1.创建?个Java项?。 2.创建?个HungrySingleton类。
3.从HungrySingleton类获取唯?的对象。
4.执?程序,输出结果。 3.2 懒汉式什么时候使用对象,什么时候创建对象 3.2.1 懒汉式线程不安全 3.2.1.1 懒汉式线程不安全介绍 是否Lazy初始化:是 (懒汉式是在对象真正需要被实例化的时候,才去创建对象) 是否多线程安全:否 (多线程同时进行到if时,可能创建多个instance) 描述:这种?式是最基本的实现?式,这种实现最?的问题就是不?持多线程。因为没有加锁synchronized,所以严格意义上它并不算单例模式。 这种?式lazy loading很明显,不要求线程安全,在多线程不能正常?作。 3.2.1.2 懒汉式线程不安全案例 1.创建?个LazySingleton类。
2.从LazySingleton类获取唯?的对象。
3.执?程序,输出结果。 3.2.2 懒汉式线程安全 3.2.2.1 懒汉式线程安全介绍 是否Lazy初始化:是 是否多线程安全:是 (加了锁) 描述:这种?式具备很好的lazy loading,能够在多线程中很好的?作,但是效率很低,99%情况下不需要同步。 优点:第?次调?才初始化,避免内存浪费。 缺点:必须加锁synchronized才能保证单例,但加锁会影响效率。 getInstance()的性能对应?程序不是很关键(该?法使?不太频繁)。 3.2.2.2 懒汉式线程安全案例 对原来类中的getInstance()方法?synchronized修饰。
3.3 双检锁/双重校验锁处在懒汉式的基础上,比懒汉式更高效 3.3.1 双检锁/双重校验锁介绍 是否Lazy初始化:是 是否多线程安全:是 描述:双检锁/双重校验锁(DCL,即double-checked locking),这种?式采?双锁机制,安全且在多线程情况下能保持?性能。 getInstance()的性能对应?程序很关键。 3.3.2 双检锁/双重校验锁案例 volatile是?个特征修饰符(type specifier)。volatile的作?是作为指令关键字,在指令层面保证当前对象的值不会被误读或恶意修改,确保本条指令不会因编译器的优化?省略,且要求每次直接读值。简单地说就是防?编译器对代码进?优化。 1.创建?个DCLSingleton类。
2.从DCLSingleton类获取唯?的对象。
3.执?程序,输出结果。 3.4 登记式/静态内部类内部类只有在外部类被调用才加载,产生INSTANCE实例,又不用加锁,此模式有懒汉式 和饿汉式的优点,屏蔽了他们的缺点,是最好的单例模式 3.4.1 登记式/静态内部类介绍 是否Lazy初始化:是 (在一开始的时候内部类不会被加载,内部类只有被调用的时候才会被加载) 是否多线程安全:是 (classloader机制为其自动加了锁) 描述:这种?式能达到双检锁?式?样的功效,但实现更简单。对静态域使?延迟初始化,应使?这种?式?不是双检锁?式。这种?式只适?于静态域的情况,双检锁?式可在实例域需要延迟初始化时使?。 这种?式同样利?了classloader机制来保证初始化instance时只有?个线程,它跟饿汉式不同的是:饿汉式只要HungrySingleton类被装载了,那么instance就会被实例化(没有达到lazy loading效果),?这种?式是RegisterSingleton类被装载了,instance不?定被初始化。因为Test_RegisterSingleton类没有被主动使?,只有通过显式调?getInstance?法时,才会显式装载SingletonHolder类,从?实例化instance。想象?下,如果实例化instance很消耗资源,所以想让它延迟加载,另外???,还要保证多线程安全,因为不能确保Singleton类还可能在其他的地?被主动使?从?被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种?式相?饿汉式?式就显得很合理。 3.4.2 登记式/静态内部类案例 1.创建?个RegisterSingleton类。
2.从RegisterSingleton类获取唯?的对象。
3.执?程序,输出结果。 3.5 枚举式3.5.1 枚举式介绍 是否Lazy初始化:否 是否多线程安全:是 描述:这种实现?式还没有被?泛采?,但这是实现单例模式的最佳?法。它更简洁,?动?持序列化机制,绝对防?多次实例化。 这种?式是Effective Java作者Josh Bloch提倡的?式,它不仅能避免多线程同步问题,?且还?动?持序列化机 制,防?反序列化重新创建新的对象,绝对防?多次实例化。不过由于JDK1.5后才加?enum特性,?这种?式写 不免让?感觉?疏,在实际?作中,也很少?。 不能通过reflection attack来调?私有构造?法。 3.5.2 枚举式案例 1.创建?个EnumSingleton枚举类。
? 2.从EnumSingleton枚举类获取唯?的枚举类型数据。
? 3.执?程序,输出结果。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 6:52:08- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |