设计模式(三)——JDK中的那些单例

实战指南:CentOS 7下VOS3000 8.0从零部署到授权激活全流程 本文提供了一份详尽的CentOS 7系统下部署VOS3000 8.0的实战指南。从环境准备、使用FileZilla上传安装包、执行自动化安装脚本,到获取软件码、利用注册机生成授权文件并激活,手把手带领用户完成从零部署到投入商用的全流程,确保系统稳定运行。 阅读详情

设计模式(二)——单例模式中介绍了单例的概念、用途、实现方式、如何防止被序列化破坏等。单例模式在JDK源码中也有多处应用。本文通过JDK(java 8)中几个典型的单例的使用来复习一下单例模式,并且通过这种实际应用来深入理解一下单例的用法与实现方式。

java.lang.Runtime

Runtime类封装了Java运行时的环境。每一个java程序实际上都是启动了一个JVM进程,那么每个JVM进程都是对应这一个Runtime实例,此实例是由JVM为其实例化的。每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。

由于Java是单进程的,所以,在一个JVM中,Runtime的实例应该只有一个。所以应该使用单例来实现。

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    private Runtime() {}
}

以上代码为JDK中Runtime类的部分实现,可以看到,这其实是饿汉式单例模式。在该类第一次被classloader加载的时候,这个实例就被创建出来了。

一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用。


GUI中的单例

除了Runtime是典型的单例以外。JDK中还有几个类是单例的,他们都是GUI中的类。这几个单例的类和Runtime最大的区别就在于他们并不是饿汉模式,也就是他们都是惰性初始化的懒汉单例。如果分析其原因的话也比较简单:那就是他们并不需要事先创建好,只要在第一次真正用到的时候再创建就可以了。因为很多时候我们并不是用Java的GUI和其中的对象。如果使用饿汉单例的话会影响JVM的启动速度。

由于Java的强项并不是做GUI,所以这几个类其实并不会经常被用到。笔者也没用过。把代码贴到这里,从单例的实现的角度简单分析一下。

java.awt.Toolkit#getDefaultToolkit()

public abstract class Toolkit {
    /**
     * The default toolkit.
     */
    private static Toolkit toolkit;

     public static synchronized Toolkit getDefaultToolkit() {
            if (toolkit == null) {
                java.security.AccessController.doPrivileged(
                        new java.security.PrivilegedAction<Void>() {
                    public Void run() {
                        Class<?> cls = null;
                        String nm = System.getProperty("awt.toolkit");
                        try {
                            cls = Class.forName(nm);
                        } catch (ClassNotFoundException e) {
                            ClassLoader cl = ClassLoader.getSystemClassLoader();
                            if (cl != null) {
                                try {
                                    cls = cl.loadClass(nm);
                                } catch (final ClassNotFoundException ignored) {
                                    throw new AWTError("Toolkit not found: " + nm);
                                }
                            }
                        }
                        try {
                            if (cls != null) {
                                toolkit = (Toolkit)cls.newInstance();
                                if (GraphicsEnvironment.isHeadless()) {
                                    toolkit = new HeadlessToolkit(toolkit);
                                }
                            }
                        } catch (final InstantiationException ignored) {
                            throw new AWTError("Could not instantiate Toolkit: " + nm);
                        } catch (final IllegalAccessException ignored) {
                            throw new AWTError("Could not access Toolkit: " + nm);
                        }
                        return null;
                    }
                });
                loadAssistiveTechnologies();
            }
            return toolkit;
        }
    }

上面的代码是Toolkit类的单例实现。这里类加载时只静态声明了私有toolkit并没有创建Toolkit实例对象,延迟加载加快了JVM启动速度。

单例模式作为一种创建模式,这里在依赖加载的时候应用了另一种创建对象的方式,不是new新的对象,因为Toolkit本身是个抽象类不能实例化对象,而是通过反射机制加载类并创建新的实例。

java.awt.GraphicsEnvironment#getLocalGraphicsEnvironment()

public abstract class GraphicsEnvironment {
    private static GraphicsEnvironment localEnv;
    public static synchronized GraphicsEnvironment getLocalGraphicsEnvironment() {
        if (localEnv == null) {
            localEnv = createGE();
        }

        return localEnv;
    }
}

这里类加载时只静态声明了私有localEnv并没有创建实例对象。在GraphicsEnvironment类被第一次调用时会创建该对象。这里没有贴出的createGE()方法也是通过反射的方式创建对象的。

java.awt.Desktop#getDesktop()

public class Desktop {

    public static synchronized Desktop getDesktop(){
        if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
        if (!Desktop.isDesktopSupported()) {
            throw new UnsupportedOperationException("Desktop API is not " +
                                                    "supported on the current platform");
        }

        sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
        Desktop desktop = (Desktop)context.get(Desktop.class);

        if (desktop == null) {
            desktop = new Desktop();
            context.put(Desktop.class, desktop);
        }

        return desktop;
    }
}

上面的代码看上去和单例不太一样。但是实际上也是线程安全的懒汉式单例。获取对象的时候先去环境容器中查找是否存在,不存在实例则创建一个实例。

以上三个类的获取实例的方法都通过同步方法的方式保证了线程安全。

Runtime类是通过静态初始化的方式保证其线程安全的。

总结

文中介绍了四个单例的例子,其中有一个是饿汉式单例,三个是懒汉式单例。通过JDK中的实际应用我们可以得出以下结论:

当一个类的对象只需要或者只可能有一个时,应该考虑单例模式。

如果一个类的实例应该在JVM初始化时被创建出来,应该考虑使用饿汉式单例。

如果一个类的实例不需要预先被创建,也许这个类的实例并不一定能用得上,也许这个类的实例创建过程比较耗费时间,也许就是真的没必须提前创建。那么应该考虑懒汉式单例。

在使用懒汉式单例的时候,应该考虑到线程的安全性问题。

28-Halcon-- union_object_model_3d函数功能(用于3D模型融合) Halcon算子union_object_model_3d是专业的3D模型融合工具,主要用于多视图拼接、部件组装和多源数据融合。该算子支持点云、网格和参数化模型输入,提供多种融合算法选择,包括基础点云拼接('points_cloud')、网格融合('mesh')和精确CAD布尔运算('cad')。工业应用涵盖逆向工程扫描拼接、汽车部件虚拟装配等场景,支持性能优化如空间分区和流式处理。算子还解决颜色属性融合、法向量保留等特殊需求,并提供拼接误差分析、拓扑验证等质量评估手段。最佳实践包含动态场景重建工作流和CA 阅读详情

相关推荐

Java常用的3中设计模式代码即工厂模式、单例模式、观察者模式demo

java 设计模式Demo 其中对单例模式做了详细的讲解,及性能和线程安全方面的优化其中Singleton.java为经典单例模式

【源码分析设计模式 1】JDK中的单例模式

一、基本介绍 单例模式比较简,可以说没有复杂的调用和接口的设计,就是一个简的类,只是要求这个类只生成一个对象,无论什么时候都要保证这一点,因此只能生成一个实的模式就是单例模式单例模式要素 1、私有构造方法; 2、私有静态引用指向自己实 ; 3、以自己实为返回值的公有静态方法; 二、类的加载 类的加载是通过类加载器(Classloader)完成的,它既可以是饿汉式加载类,也可以是懒汉式加载,这跟不同的JVM实现有关。加载完类后,类的初始化就会发生,如果是对一个类的主动使用就会初始化

学Java,找哪吒 1万+

这篇文章详细介绍了《考虑超短期负荷预测的火储联合一次调频控制策略》的研究成果和技术实现(含详细代码及解释)

内容概要:该论文提出了一种结合超短期负荷预测的火储联合一次调频控制策略,旨在提高储能辅助火电机组参与调频的稳定性和可靠性。策略采用双层控制结构:负荷预测层使用图卷积网络-双向门控循环元与改进时序卷积网络的组合模型进行超短期负荷预测;一次调频层则基于预测结果,采用改进蜻蜓算法动态调整虚拟下垂和惯性控制的位调节功率,以最小化频率偏差。仿真结果表明,该策略能有效改善调频效果并优化电池荷电状态。此外,文中还提供了详细的Python代码实现,包括数据预处理、组合预测模型构建、改进蜻蜓算法、一次调频控制策略以及仿真测试,验证了策略的有效性。适合人群:电力系统研究人员、从事火电机组与储能系统联合调频工作的工程师和技术人员,尤其是具备一定编程基础,对机器学习和优化算法有一定了解的专业人士。使用场景及目标:①适用于火电机组与储能系统联合调频的实际应用场景;②目标是提高调频的稳定性和可靠性,优化电池荷电状态,减少频率偏差,确保电网频率稳定。其他说明:该策略不仅通过理论分析和仿真验证了其有效性,还提供了完整的代码实现,方便读者进行复现和进一步研究。此外,文中还讨论了该策略在实际工程中的应用前景和可能的改进方向,如考虑多储能元的协同控制、计及电池老化成本的优化目标等。

设计模式实战——开发中常用到的单例模式

定义:单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实,并提供一个全局访问点来获取这个实。特点一实:通过私有构造函数或静态方法确保整个应用中只存在一个实对象。全局访问点:提供一个静态方法供外部调用,以获取该类的唯一实。延迟初始化:在需要时才创建实,以节省资源并提高效率。JDK中的单例模式主要体现在Runtime类和GUI相关类中。Runtime类定义与特点。

2301_76419561的博客 1563

单例模式jdk中的应用

单例模式

just_do_it978的博客 500

(转载)Swing中的AppContext使用

来自http://www.javafaq.nu/java-bookpage-13-5.html 2.5    AppContext service class sun.awt.AppContext [platform specific]   Warning: AppContext is not meant to be used by any developer, as it is n...

kurttlin的博客 600

JDK中的设计模式单例模式

1JDK单例模式的体现 首先看一下一段JDK 源码中的Runtime类的一段代码 public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; }...

344

设计模式之面试题

设计模式是一套反复使用、多人知晓的,经过分类编写、代码设计经验的总结。在GOF编写的设计模式一书中说道:本书设计的设计模式并不描述新的或者未经证实的设计,我们只收录那些在不同系统中多次使用过的成功设计。大部分设计模式要解决的都是代码的可重用性、可拓展性的问题。如果说数据结构和算法是教你如何写出高效代码,那设计模式讲的是如何写出可拓展、可读、可维护的高质量代码,所以,它们跟平时的编码有直接的关系,也会直接影响到你的开发能力。

weixin_43247990的博客 394

JDK中使用的设计模式

关于JDK里的设计模式,也有人总结过JDK里的设计模式,但是没有更进一步的展示,本文具体看看实现是什么样的。调用getBundle时,调用了BundleReference的方法,而这个方法本身是在抽象类Reference中的,大体是满足这个定义的。将一个复杂对象的构建(Director)与它的表示(Builder)分离,使得同样的构建过程可以创建不同的表示(ConcreteBuilder)。这里有一个问题:作为装饰器,是要感知被装饰的对象的类型或接口的,否则没有办法递归地调用被装饰对象的方法。

UotbLXG2A的博客 200

23种设计模式

动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)基本介绍组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式。组合模式使得用户对个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象。

2503_92462323的博客 255

Java基础(二十)——JDK中的设计模式(各设计模式的作用,jdk中的体现)

JDK中的设计模式设计模式的作用,jdk中的体现

weixin_45864705的博客 2022

JDK中的设计模式

类间关系 继承、委托、依赖、聚合、组合 经典设计模式JDK中的体现 1.Singleton() 作用:保证类只有一个实;提供一个全局访问点 JDK中体现: (1)Runtime (2)NumberFormat 类图: 2.Factory(静态工厂) 作用: (1)代替构造函数创建对象 (2)方法名比构造函数清晰 JDK中体现: (1)Integer.valueOf (2)Class.f...

qq_38311489的博客 3535

JDK和Spring中的设计模式

JDK中的设计模式(17) 创建型 1)工厂方法 Collection.iterator() 由具体的聚集类来确定使用哪一个Iterator 2)单例模式 Runtime.getRuntime() 3)建造者模式 StringBuilder 4)原型模式 Java中的Cloneable 结构性 1)适配器模式 InputStreamReader OutputStreamW...

少说,多做。 9459

JDK源码看设计模式:工厂、与观察者模式的典型实现

阅读Java源码并非一蹴而就的任务,而是一个持续的、积累的过程。随着项目经验的增长,反复回过头来重读源码,每次都会有新的收获。《深入探索Java源码:从基础类库到核心框架的逐行解析》这类书籍的价值,在于它为我们提供了一条清晰的路径和深度解读。在云原生和微服务架构大行其道的今天,对底层原理的深刻理解(如NIO、并发编程)显得愈发重要。无论是为了更好地使用Spring等主流框架,还是为了设计出高并发、低延迟的系统,扎实的源码功底都是你最坚实的后盾。

ql010204的博客 813

jdk中的23种设计模式体现

[设计模式]JDK中的设计模式 本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图。 首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK设计模式有所帮助。 一、设计模式是什么 (1)反复出现问题的解决方案 (2)增强软件的灵活性 (3)适应软件不断变化 二、学习JDK设计模式的好处 (1)借鉴优秀代码的设计,有助于提高代码设计能力 (2)J

李凯龙 1602

JDK设计模式

本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图。 首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK设计模式有所帮助。 一、设计模式是什么 (1)反复出现问题的解决方案 (2)增强软件的灵活性 (3)适应软件不断变化 二、学习JDK设计模式的好处 (1)借鉴优秀代码的设计,有助于提高代码设计能力 (2)JDK的设计中体现了大多数设计模式,是学习设计模式的较好的方式 (3)可以更加深入的了解JDK 、类间关系 继承、委托、依赖、聚合、组合 四、介绍

星星的技术专栏 2万+

设计模式jdk、spring中的应用

本文主要是归纳了JDK中所包含的设计模式和spring中包含的设计模式,包括作用和其设计类图。首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK设计模式有所帮助。一、设计模式是什么(1)反复出现问题的解决方案(2)增强软件的灵活性(3)适应软件不断变化二、学习JDK设计模式的好处(1)借鉴优秀代码的设计,有助于提高代码设计能力(2)JDK的设计中体现了大多数设计模式,是学习设计...

wenjieyatou的博客 2053

JavaJDK设计模式

文章目录1 JDK设计模式1.1 问题引入1.2 jdk设计模式1.2.1 Singleton()1.2.2 Factory(静态工厂)1.2.3 Factory Method(工厂方法)1.2.4 bstract Factory(抽象工厂) 1 JDK设计模式 1.1 问题引入 本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图。 首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK设计模式有所帮助。 设计模式是什么: 反复出现问题的解决方案 增强软件的灵活性 适应软件

上善若泪 593
上一篇: 设计模式(二)——单例模式
下一篇: 单例模式的七种写法
feel369
博客等级 码龄5年 5粉丝 · 0原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值