大学之道,在明明德,在亲民,在止于至善。 《礼记 大学》
今天考完了安卓这门课,100分钟的考试50分钟就交卷离开考场了,回想一下大学生活就这么没了,虽然小菜现在还是大三但是大四学校安排是实习到下年四月份,学校里面已经没有了课程。想想自己的青春就这么没了,也是有点伤感呢。。最近在看《研读设计模式》这本书感觉写的很不错,通俗易懂哈。
之前写过懒汉式单例模式在多线程环境下,会造成不只创建出一个实例的问题,下面是提出的几种解决方式以及他们分别出现的问题:
- 使用双重检验锁; 问题:JVM为了使得处理器内部的运算单元能充分利用,处理器可能会对输入代码进行乱序执行
- 在双重检验锁的基础上给对象加volatile修饰用来解决乱序执行的问题。问题:volatile关键字可能会屏蔽掉虚拟机中一些必要的代码优化,所以运行效率不会很高。所以在项目开发中这种方式也不要大量使用。
那么既然上面的解决方式都有一些小小的瑕疵,那么还有什么比较合适的方式呢?
其中的一种方式就是使用类级静态内部类。第二种方式就是使用使用枚举类型。
在多线程中,为了解决并发问题,我们主要是使用synchronized来加互斥锁进行同步。有些时候我们的jvm默认的已经为我们解决了多线程情况下的并发问题。其中包括:
- 静态初始化器初始化静态字段,代码块的时候
- 访问final字段的时候
采用静态初始化器初始化对象,这种方式很好理解,比如jvm在加载一个类时对其静态属性进行初始化的过程就是线程安全的,比如饿汉式单例模式中就使用的这种方式初始化对象的。但是这种方式是比较消耗资源的,因为它不管我们使不使用这个对象在加载类的时候它都会被创建出来从而占用一些不必要的内存。我们可以去假设一种方式让静态初始化器在装载类的时候不去初始化对象。
我们其实可以使用类级静态内部类的方式解决这个问题,为了更好的说明这个问题,我们先看下面这个例子
public class SingleIntance { private static class SingleHandler { private static SingleIntance singleIntance = new SingleIntance(); } public void doSpeak() { System.out.println("I am a coder"); } private SingleIntance() { } public static SingleIntance getSingleInstance() { return SingleHandler.singleIntance; } public static void main(String[] args) { SingleIntance intance = SingleIntance.getSingleInstance(); intance.doSpeak(); } }
这是这本书上给出的方案,我仔细揣摩感觉这种方式非常不错,也希望和大家分享一下这种方式。首先分析一下这种方式:SingleIntance这个类在进行装载的时候并不会装载SingleHandler这个静态内部类,当我们在第一次调用getSingleInstance这个方法的时候。SingleHandler.singleIntance这行代码会让虚拟机加载SingleHandler 这个内部类,并初始化其静态属性,虚拟机只会对一个类初始化一次,所以这样虚拟机就保证了单例对象只被初始化一次。这种方式的好处就是getSingleInstance并没有被同步,对其进行延迟加载并没有带来任何的访问成本,效率大大增强。
第二种方式就是使用枚举来实现单例模式,按书中的说法《高效java第二版》中说道:单元素的枚举类型已经成为实现SingleIntance的最佳方式。java中的枚举类型启示是功能齐全的类可以有字段和方法,以前小菜只用到了枚举中的属性,方法并没有用到。看来好多知识都需要再补补了。java枚举类型的基本思想是通过共有的静态final域为每个枚举常量导出实例的类。下面看一个非常简单的例子:
public enum EnumSingleInstance { /** * 定义枚举元素,该元素就是一个单例的对象 */ singleInstance; public void doSpeak(){ System.out.println("I am a single object"); } public static void main(String[] args) { EnumSingleInstance instance=EnumSingleInstance.singleInstance; instance.doSpeak(); } }
由以上代码可以看到用枚举来控制单实例的方式比其他方式会便捷很多,而且还无偿的提供了序列化的支持,由JVM保证只有一个实例,防止有多个实例。
现在是凌晨1:26好晚了,洗洗睡了。
相关推荐
单例模式是一种常用的设计模式,它...同时,设计模式的应用不仅仅局限于单例,还有工厂模式、观察者模式、装饰者模式等,它们都是软件设计中常用的最佳实践,能够帮助我们更好地组织代码,提高代码的可读性和可维护性。
在Java中,实现单例模式有多种方法,包括懒汉式(线程不安全)、饿汉式、双重检查锁定(DCL)以及枚举方式。其中,DCL和枚举方式是推荐的,因为它们既保证了线程安全,又避免了不必要的同步开销。 单例模式的Java...
以上就是Java中常见的单例模式实现方式,每种方式都有其适用场景和优缺点。在实际开发中,应根据项目需求和环境选择合适的方法。例如,如果对性能要求较高,可能会选择静态内部类或枚举方式;如果需要考虑序列化问题...
### 设计模式之单例模式 #### 概述 单例模式(Singleton Pattern)是软件设计模式中的一个重要组成部分...在实际项目中,根据具体需求选择合适的实现方式,可以更好地发挥单例模式的优势,提高程序的效率和可维护性。
单例模式是软件设计模式中的一种基础且广泛应用的模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java中,实现单例模式有多种...在理解了各种实现方式后,才能更好地利用单例模式解决实际问题。
总结来说,这个Python实现的单例模式日志记录器结合了设计模式与日志管理的最佳实践,确保在整个应用程序中只有一个日志记录器实例,方便管理和共享。通过这种方式,我们可以有效地跟踪程序运行状态,同时避免了资源...
内容概要:本文档介绍了三个经典的软件设计模式——单例模式(Singleton Pattern)、工厂模式(Factory Pattern)以及观察者模式(Observer Pattern)的具体实现,并给出了带有详细注释的C++代码范例。对每个设计模式都有...
### PHP设计模式之单例模式详解 #### 一、引言 在软件工程领域,设计模式是一种被广泛接受的解决方案,用于解决特定类型的问题。PHP作为一种流行的服务器端脚本语言,同样可以从这些设计模式中受益。本文将详细介绍...
在JavaScript这样的动态语言中,单例模式的实现方式很多样,而且可以非常灵活。下面,我们就来深入探讨单例模式在JavaScript中的实现以及相关知识点。 首先,单例模式的基本概念是通过一个构造函数来封装创建一个...
在编程领域,设计模式是一种被广泛接受的解决常见问题的模板或最佳实践。Java作为一款广泛应用的面向对象的编程语言,其设计模式的应用...通过学习和熟练掌握这些设计模式,开发者能够更好地应对复杂软件工程的需求。
在本文中,我们将深入探讨三种工厂设计模式——简单工厂模式、抽象工厂模式和工厂方法模式,以及两种单例模式——饿汉单例模式和懒汉单例模式。这些模式都是面向对象设计中的重要组成部分,对于理解和构建可维护、可...
对于频繁使用的对象,可以缩减系统的开销,特别是当对象需要频繁地进行销毁和创建时,单例模式无疑能提供更好的性能。 单例模式具有一定的“防并发作用”,由于单例模式只生成一次实例化对象,可以减少系统内存的...
在软件开发中,设计模式是一种在特定情境下解决常见问题的经验总结,被广泛应用于各种编程语言中。在Qt框架中,单例设计模式是一...通过学习和实践,你将能够更好地理解和运用Qt中的单例设计模式,提升你的Qt编程技能。
在《设计模式》第二版中,刘伟老师深入讲解了单例模式,本压缩包中的"单例模式习题6"和"单例模式习题7"可能是书中的课后练习,旨在帮助读者更好地理解和运用单例模式。 单例模式的核心思想是控制类的实例化过程,...
单例模式是软件设计模式中的一种经典模式,用于确保一个类只有一个实例,并提供一个全局访问点。...通过学习和实践这些单例模式的实现,我们可以更好地理解和应用设计模式,提升代码的质量和可维护性。
根据实现方式不同,单例模式可以分为“饿汉式”和“懒汉式”。饿汉式在类加载时就创建实例,而懒汉式则在首次使用时创建实例,懒汉式通常需要考虑线程安全问题,因此在实现时需要多加小心。单例模式在许多场景中都有...
- 实现单例模式通常有懒汉式、饿汉式和双重检查锁定等方式,选择哪种方式取决于线程安全需求和性能考虑。 3. **缺省适配器模式(Default Adapter Pattern)**: - 当一个类需要使用某个接口,但不希望实现所有的...