`

单例模式——Singleton

 
阅读更多

单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。正是由于这个特 点,单例对象通常作为程序中的存放配置信息的载体,因为它能保证其他对象读到一致的信息。例如在某个服务器程序中,该服务器的配置信息可能存放在数据库或 文件中,这些配置数据由某个单例对象统一读取,服务进程中的其他对象如果要获取这些配置信息,只需访问该单例对象即可。这种方式极大地简化了在复杂环境 下,尤其是多线程环境下的配置管理,但是随着应用场景的不同,也可能带来一些同步问题。

1.最简单的实现方式如下:

public class Singleton {    
      //用一个静态变量来记录Singleton类的唯一实例   
    private static Singleton uniqueInstance;   
    
      private Singleton() {}   
           
      //注意这个方法也是静态的   
      public static Singleton getInstance() {    
           if(uniqueInstance == null) {   
             uniqueInstance = new Singleton();   
           }   
           return uniqueInstance;   
      }   
}  

 

上述实现方式,在单线程时是没有问题的,但是在多线程时,便会产生线程安全问题了.如果第一个线程发现了成员变量现在为空的时候,准备创建对象时,第二个线程也发现了成员变量为空,也会继续再创建一个对象,这样就会造成JVM中有多个单例类型的实例。而如果这个单例类型的成员变量在运行过程中变化,将会造成多个单例类型实例的不一致,产生一些很奇怪的现象。

2.使用synchronized关键字锁定整个方法确保getInstance()方法一次只能被一个线程调用

public class Singleton { 
    //用一个静态变量来记录Singleton类的唯一实例   
   private static Singleton uniqueInstance;   
    
    private Singleton() {}   
           
    //注意这个方法也是静态的   
   public static synchronized Singleton getInstance() {    
        if(uniqueInstance == null) {   
             uniqueInstance = new Singleton();   
         }   
         return uniqueInstance;   
    }   
}  

 

 但很多时候我们通常会认为锁定整个方法的是比较耗费资源的,代码中实际会产生多线程访问问题的只有 instance = new Singleton(); 这一句,为了降低 synchronized 块性能方面的影响,只锁定instance = new Singleton();

public class Singleton {    
  
    private volatile static Singleton uniqueInstance;   
    
    private Singleton() {}   
           
    public static Singleton getInstance() {    
    if(uniqueInstance == null) { //(1)   
        //只有第一次才彻底执行这里的代码   
       synchronized() {   
          //再检查一次   
          if(uniqueInstance == null)   
        uniqueInstance = new Singleton();   
       }   
    }   
         return uniqueInstance;   
    }   
}  

 同时也可以使用急切创建实例,而不用延迟实例化的做法:

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

 private static Singleton uniqueInstance = new Singleton();  在静态初始化器(static initializer)中创建单例,这保证了线程安全。利用这个做法,JVM在加载这个类时马上创建此唯一的单件实例。JVM保证任何线程访问uniqueInstance静态变量之前,一定先创建些实例。

 还有一种方式则更加灵巧,没有使用同步但保证了只有一个实例,还同时具有了Lazy的特性:

public class ResourceFactory {      
    private static class ResourceHolder {      
        public static Resource resource = new Resource();      
     }      
     
    public static Resource getResource() {      
        return ResourceFactory.ResourceHolder.resource;      
     }      
     
    static class Resource {      
     }      
}    

 上面的方式是值得借鉴的,在ResourceFactory中加入了一个私有静态内部类ResourceHolder ,对外提供的接口是 getResource()方法,也就是只有在ResourceFactory .getResource()的时候,Resource对象才会被创建,这种写法的巧妙之处在于ResourceFactory 在使用的时候ResourceHolder 会被初始化,但是ResourceHolder 里面的resource并没有被创建,这里隐含了一个是static关键字的用法,使用static关键字修饰的变量只有在第一次使用的时候才会被初始化,而且一个类里面static的成员变量只会有一份,这样就保证了无论多少个线程同时访问,所拿到的Resource对象都是同一个。

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    c#单例模式(Singleton)的6种实现

    如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公用的实例,这就是我们今天要介绍的——单例模式(Singleton)。  使用频率高 单件模式(Singleton...

    设计模式——单例模式

    **设计模式——单例模式** 在软件工程中,设计模式是一种在特定场景下解决常见问题的标准方案,可以被复用并提升代码质量。单例模式是设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式...

    设计模式——单例模式(懒汉模式)

    单例模式是软件设计模式中的一种经典模式,它保证了类在任何情况下都只有一个实例存在。这个模式在很多场景下非常有用,例如控制全局资源、管理配置信息等。本文将详细探讨单例模式的懒汉式实现,并结合源码进行解析...

    设计模式——策略模式 & 单例模式

    策略模式和单例模式是软件设计中两种非常重要的设计模式,它们在实际开发中有着广泛的应用。在这篇文章中,我们将深入探讨这两种模式的核心概念、实现方式以及如何在实际项目中运用。 策略模式是一种行为设计模式,...

    IOS应用源码——Singleton.rar

    这个Singleton.rar文件很可能是包含了一个或多个使用了单例模式的iOS应用源代码示例。让我们深入探讨一下单例模式在iOS开发中的运用及其重要性。 首先,单例模式的主要优点在于它能有效地管理资源,特别是当资源...

    单例模式应用场景

    其中,单例模式(Singleton Pattern)作为最简单的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。尽管有些设计模式专家认为它过于简单而不能称为真正的“模式”,但单例模式因其简洁性和实用性...

    单例 模式 singleton

    单例模式是一种设计模式,用于确保一个类在整个应用程序中只存在一个实例。这种模式在Java中广泛应用于需要全局访问点或资源管理的场景,比如配置管理、数据库连接池等。下面将详细阐述单例模式的实现方式、优化策略...

    2种单例模式:1赖汉式:2饿汉式

    这里我们将详细探讨标题中提到的两种单例模式——"懒汉式"(Lazy Initialization)和"饿汉式"(Eager Initialization)。 1. **饿汉式单例模式** 饿汉式单例的特点是类加载时就完成了实例化,确保了线程安全,但...

    设计模式实现——单例模式

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制共享资源、管理系统级别的服务或者简化对象间的交互。单例模式的核心在于...

    设计模式-单例模式

    **设计模式——单例模式** 单例模式是一种广泛应用于软件设计中的创建型设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于控制共享资源的访问,比如线程安全的数据库连接池...

    C++中的三大设计模式:单例模式、工厂模式与观察者模式的代码实现

    内容概要:本文档介绍了三个经典的软件设计模式——单例模式(Singleton Pattern)、工厂模式(Factory Pattern)以及观察者模式(Observer Pattern)的具体实现,并给出了带有详细注释的C++代码范例。对每个设计模式都有...

    C#设计模式(1)——单例模式.pdf

    本次将聚焦于一种较为简单的模式——单例模式。 #### 单例模式概述 单例模式是一种创建型模式,它的核心在于确保某个类只有一个实例,并提供一个全局可访问的访问点。这种模式非常实用,尤其是在需要频繁地创建和...

    设计模式——单例

    设计模式是软件工程中的一种最佳实践,用于解决在不同场景下重复出现的问题。...通过阅读提供的"iOS 设计模式——单例"相关资料,可以深入理解在iOS开发环境中如何有效利用单例模式来优化代码结构和提高程序性能。

    java设计模式之——单例模式

    单例模式是软件设计模式中的一种经典模式,其主要目的是控制类的实例化过程,确保在任何情况下,一个类只有一个实例存在。这种模式通常用于管理共享资源或者全局配置,例如数据库连接池、线程池、日志服务等。在Java...

    单例模式(Singleton Pattern)

    单例模式是设计模式中的一种,它用于控制类的实例化过程,确保在整个应用程序中,对于特定类,只有一个实例存在。这种模式常被用来管理共享资源或者全局配置,以提高性能和减少系统间的耦合。 单例模式的核心在于...

    IOS应用源码——单例模式.zip

    在iOS应用开发中,单例模式是一种常用的软件设计模式,它保证了类只有一个实例,并提供一个全局访问点。这个模式在iOS中尤其常见,因为许多系统服务和组件就是通过单例来实现的,例如UIApplication、NSFileManager等...

    设计模式之单例模式Java实现和类设计图

    本次我们将深入探讨两种设计模式——单例模式和装饰模式,它们在Java编程中都有着广泛的应用。 首先,让我们来理解“单例模式”。单例模式是一种创建型设计模式,其核心思想是保证一个类只有一个实例,并提供一个...

    android开发设计模式之——单例模式详解

     单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点 二、适用场景 1. 应用中某个实例对象需要频繁的被访问。 2. 应用中每次启动只会存在一个实例。如账号系统,数据库系统。 三、常用...

Global site tag (gtag.js) - Google Analytics