【HeadFirst 设计模式学习笔记】5 单例模式

简介:

1.单例模式确保一个实例被创建,并且任意时刻都只有一个对象。它给了我们一个全局的访问点,又屏蔽了全局变量的缺点。可以被用来管理共享资源,比如数据库连接或线程池。特征是构造函数为私有,然后声明一个私有静态成员作为类对象,对外提供一个静态类方法创建该对象,在创建对象时会先判断是否已经创建,若是则直接返回已经创建的对象,若没有则创建新对象。

2.经典的单例模式如下:

public class Singleton { 
    private static Singleton uniqueInstance; 
    // other useful instance variables here 
    private Singleton() {} 
    public static Singleton getInstance() { 
        if (uniqueInstance == null) { 
            uniqueInstance = new Singleton(); 
        } 
        return uniqueInstance; 
    } 
    // other useful methods here 
}

这个是线程不安全的,因为在同一时刻可能两个线程都进入了getInstance中创建新的Singleton,导致唯一性不能保证。

3.多线程安全的单例模式如下:

public class Singleton { 
    private static Singleton uniqueInstance; 
    // other useful instance variables here 
    private Singleton() {} 
    public static synchronized Singleton getInstance() { 
        if (uniqueInstance == null) { 
            uniqueInstance = new Singleton(); 
        } 
        return uniqueInstance; 
    } 
    // other useful methods here 
}

使用一个synchronized 限定符对创建实例的方法进行同步,可以完成线程安全的需求,但是若已经创建后则同步这一动作是多余且降低效率的。若程序对这部分的效率不关注则使用该方法即可。

4.若总是使用该单例模式,则可以使用“急切”方式进行单例模式调用,利用了JVM加载类时会马上创建该实例的特性,这保证了线程安全,但是这又有和全局变量一样的问题——若这个对象耗资源很大,而程序在执行中又一直没有使用它,那么就造成了资源浪费:

public class Singleton { 
private static Singleton uniqueInstance = new Singleton(); 
    private Singleton() {} 
    public static Singleton getInstance() { 
        return uniqueInstance; 
    } 
}

5.一个比较周全的方式是用“双重检查加锁”的方式减少同步次数的同时又线程安全。注意JAVA5前不支持volatile关键字。

public class Singleton { 
    private volatile static Singleton uniqueInstance;//volatile 确保当uniqueInstance初始化为Singleton的实例时,多个线程可以正确的处理uniqueInstance变量。 
    private Singleton() {} 
    public static Singleton getInstance() { 
        if (uniqueInstance == null) {//只有第一次才会执行这里面的代码。也就是说第一次为同步,后来就是不作为了——这就是我们要的效果。 
            synchronized (Singleton.class) { 
                if (uniqueInstance == null) { 
                    uniqueInstance = new Singleton(); 
                } 
            } 
        } 
        return uniqueInstance; 
    } 
}

6.注意事项:

1)单例类不能被继承,因为Java中私有构造方法的无法扩展类。

2)和全局变量相比的优缺点,请参照“急切”和“延迟”两种单件模式实现的方式进行类比分析。

3)若使用多个类加载器,则可能导致单例失效。




本文转自gnuhpc博客园博客,原文链接:http://www.cnblogs.com/gnuhpc/archive/2012/12/17/2822409.html,如需转载请自行联系原作者

相关文章
|
11天前
|
设计模式 存储 前端开发
前端必须掌握的设计模式——单例模式
单例模式是一种简单的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。适用于窗口对象、登录弹窗等场景,优点包括易于维护、访问和低消耗,但也有安全隐患、可能形成巨石对象及扩展性差等缺点。文中展示了JavaScript和TypeScript的实现方法。
|
16天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
21 2
|
1月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
36 4
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
22天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
1月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
20 1
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
27 0
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###