[zt]Singleton和Double-Checked Locking设计模式—UML图及代码实现

简介:

Singleton和Double-Checked Locking设计模式,分别指的是单例模式和双重检查锁模式,它们都可以用于确保某个类只有一个对象实例化。

两个模式的区别在于:Singleton模式用在单线程应用程序中,而Double-Checked Locking模式用于多线程模式。

一、Singleton模式

UML图:

代码:

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. package bupt.xujinliang.singletonpattern;  
  2. /** 
  3.  *  
  4.  * @author jin 
  5.  * 
  6.  */  
  7. public class SingletonExample {  
  8.     public static void main(String[] args) {  
  9.         Printer printer1 = Printer.getInstance();  
  10.         Printer printer2 = Printer.getInstance();  
  11.         if(printer1 == printer2) {  
  12.             System.out.println("printer2 point to the same address with printer1");  
  13.         } else {  
  14.             System.out.println("printer2 point to different address with printer1");  
  15.         }  
  16.     }  
  17. }  
  18. class Printer {  
  19.     private static Printer instance;  
  20.     public Printer() {  
  21.         System.out.println("Printer Constructor");  
  22.     }     
  23.     public static Printer getInstance() {  
  24.         if(null == instance)   
  25.             instance = new Printer();  
  26.         return instance;  
  27.     }  
  28. }  


运行结果:

 

2.Double-Checked Locking模式

Double Check Locking模式是singleton的多线程版本,必须使用锁来锁定临界区,当多个线程存在访问临界区的意图时,保证了临界区只被访问一次。
首先介绍其在C/C++环境下的实现过程:
代码1:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. Printer* get_instance(void)  
  2. {  
  3.     lock();  
  4.     if( instance == 0) {  
  5.        instance = new Printer;  
  6.     }  
  7.     unlock();  
  8.     return instance;  
  9. }  
上述代码存在的问题是:无论是否已经初始化都要加锁,增加了负荷,已经没有所谓的并发性能了。
代码2:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. Printer* get_instance(void)  
  2. {   
  3.     if( instance == 0){  
  4.         lock();  
  5.         instance = new Printer;  
  6.         unlock();  
  7.     }  
  8.     return instance;  
  9. }  
上述代码存在的问题是:不能保证临界区只初始化一次,没能实现singleton的基本功能。
代码3:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. Printer* get_instance(void)  
  2. {   
  3.     if( instance == 0){  
  4.         lock();  
  5.         if( instance == 0 )  
  6.             instance = new Printer;  
  7.         unlock();  
  8.     }  
  9.     return instance;  
  10. }  
这是比较完善的Double-Checked Locking模式实现的代码。
为什么叫做Double-Checked Locking呢?请看上述代码3,可以看到在加锁前后都对instance变量进行了检查,故谓之Double-Checked Locking。
那么在Java中的实现与在C/C++中不同吗?是的。
下面的的Java代码是不能够实现Double-Checked Locking模式的:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. class Printer {  
  2.     private static Printer resource ;  
  3.     public static Printer getInstance(){      
  4.         if(resource == null ){  
  5.             synchronized (DoubleCheckedLockingExample.class) {  
  6.                 if(resource  == null ){  
  7.                     resource  = new Printer() ;  
  8.                 }  
  9.             }             
  10.         }         
  11.         return resource ;  
  12.     }     
  13.     private Printer(){}  
  14. }  
上面程序真正的问题是没有同步的情况下读取共享变量resource,并发的情况下对象的状态值有可能是过期无效的。要解决这个问题也很简单,把resource声明为volatile类型。volatile有什么作用?引用《java并发编程实战》的解析:
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. 当一个域声明为volatile类型后,编译器与运行时会监视这个变量:它是共享的,而且对它的操作不会与其他的内存操作一起被重排序。volatile变量不会缓存在寄存器或缓存在对其他处理器隐藏的地方。所以,读一个volatile类型的变量时,总会返回由某一线程所写入的最新值。  
读取volatile变量比读取非volatile变量的性能几乎没有差别,不过需要注意的是volatile只能保证内存可见性,并不能保证原子性。
现给出Java在多线程下实现单个实例化对象的方法:
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. class Printer {  
  2.     private static class Instance {  
  3.         static final Printer instance = new Printer();  
  4.     }  
  5.     private static Printer resource ;  
  6.     public static Printer getInstance(){          
  7.         return Instance.instance;  
  8.     }     
  9.     private Printer(){}  
  10. }  
上述方法之所以有效,是因为内部类(Instance)将只被装载一次,所以只会创建一个对象。

本文转自博客园Grandyang的博客,原文链接:[zt]Singleton和Double-Checked Locking设计模式—UML图及代码实现

,如需转载请自行联系原博主。

相关文章
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
2月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性和扩展性
【10月更文挑战第13天】 本文将探讨PHP中常见的设计模式及其在实际项目中的应用。通过对比传统编程方式,我们将展示设计模式如何有效地提高代码的可维护性和扩展性。无论是单例模式确保类的单一实例,还是观察者模式实现对象间的松耦合,每一种设计模式都为开发者提供了解决特定问题的最佳实践。阅读本文后,读者将能更好地理解和应用这些设计模式,从而提升PHP编程的效率和质量。
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
3月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性
设计模式在PHP开发中至关重要,如单例模式确保类仅有一个实例并提供全局访问点,适用于管理数据库连接或日志记录。工厂模式封装对象创建过程,降低系统耦合度;策略模式定义算法系列并使其可互换,便于实现不同算法间的切换。合理选择设计模式需基于需求分析,考虑系统架构,并通过测试驱动开发验证有效性,确保团队协作一致性和代码持续优化。设计模式能显著提升代码质量,解决开发中的设计难题。
34 8
|
3月前
|
设计模式 算法 PHP
PHP中的设计模式:提升代码的灵活性与可维护性
在本文中,我们将深入探讨PHP编程语言中的一种重要概念——设计模式。设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它代表了最佳的实践,被有经验的面向对象的软件开发人员所采用。本文将通过具体的实例,展示如何在PHP项目中应用设计模式,以提高代码的灵活性和可维护性。无论你是PHP初学者还是经验丰富的开发者,都能从中获得有价值的见解。
|
3月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
3月前
|
设计模式 存储 数据库连接
探索PHP中的设计模式:提高代码的可维护性与扩展性
本文将深入探讨PHP中常用的设计模式,包括单例模式、工厂模式和观察者模式。通过具体的代码示例,展示如何在实际项目中应用这些设计模式,以提高代码的可维护性与扩展性。无论你是PHP初学者还是有一定经验的开发者,都可以通过本文的学习,提升你的编程技巧和项目架构能力。
|
3月前
|
设计模式 安全 Java
设计模式--单例模式Singleton
这篇文章详细介绍了单例模式Singleton的八种实现方式,包括饿汉式(静态常量和静态代码块)、懒汉式(线程不安全和线程安全的同步方法、同步代码块)、双重检查、静态内部类和枚举。每种方式都有详细的代码示例和优缺点说明,帮助理解单例模式的应用和选择适合的实现方法。
设计模式--单例模式Singleton
|
3月前
|
设计模式 算法 搜索推荐
PHP中的设计模式:提高代码可维护性的秘诀
在本文中,我们将探讨PHP设计模式的重要性以及它们如何帮助开发者编写出更加灵活、可维护的代码。我们将介绍几种常见的设计模式,包括单例模式、工厂模式和策略模式,并通过实际示例展示它们在PHP中的应用。最后,我们会讨论何时使用这些设计模式以及在实际项目开发中的最佳实践。
40 1
|
3月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。