`

单例模式在多线程下的问题

阅读更多
单例设计模式有两种形式:一种是饥饿式

Java代码 
package net.chopsuey.singleton;  

public final class EagerSingleton  
{  
   private static EagerSingleton singObj = new EagerSingleton();  
 
    private EagerSingleton()  
    {  
    }    
    public static EagerSingleton getSingleInstance()  
    {  
        return singObj;  
    }  

package net.chopsuey.singleton;

public final class EagerSingleton
{
    private static EagerSingleton singObj = new EagerSingleton();

    private EagerSingleton()
    {
    }

    public static EagerSingleton getSingleInstance()
    {
        return singObj;
    }
}

比较明显,这种是线程安全的。因为static变量是在类被加载时(有可能没被实例化)初始化并仅被初始化一次。因为这样就可以保证只有一个singObj被初始化。

另外一种则是懒汉式

Java代码 
package net.chopsuey.singleton;  
 
public final class LazySingleton  
{  
    private static LazySingleton singObj = null;    
    private LazySingleton()  
    {  
    }  
 
    public static LazySingleton getSingleInstance()  
    {  
        if (singObj == null)  
        {  
            singObj = new LazySingleton();  
       }  
        return singObj;  
    } 
package net.chopsuey.singleton;

public final class LazySingleton
{
    private static LazySingleton singObj = null;

    private LazySingleton()
    {
    }

    public static LazySingleton getSingleInstance()
    {
        if (singObj == null)
        {
            singObj = new LazySingleton();
        }
        return singObj;
    }

这种则是线程不安全的了。因为当有多个线程一起调用getSingleInstance()时则可能会生成多个实例。因此才需要修改一下。修改为我之前的那段代码

Java代码 
package net.chopsuey.singleton;    
  
public class Singleton    
{    
    private static class SingletonHolder    
    {    
       static Singleton instance = new Singleton();    
    }    
   
    public static Singleton getInstance()    
    {    
        return SingletonHolder.instance;    
    }    

package net.chopsuey.singleton; 

public class Singleton 

    private static class SingletonHolder 
    { 
        static Singleton instance = new Singleton(); 
    } 

    public static Singleton getInstance() 
    { 
        return SingletonHolder.instance; 
    } 
}
一个静态内部类内的一个静态成员就可以保证它只在类被加载时只初始化一次。因此不管有多少个线程来调用它,都只能得到同个实例(类被加载时初始化的那个)。

分享到:
评论

相关推荐

    C++ 多线程和多线程下的单例模式

    本资源描述了C++11 中多线程的创建,C++11中std命名空间中将boost库中的Thread加入,boost多线程从准标准变为标准,其中还介绍了C++ 多线程下的单例模式的使用,本文档为txt文档

    使用C++11实现线程安全的单例模式

    线程安全的单例模式在多线程环境下尤其重要,因为不正确的实现可能导致多个线程创建多个实例,这违反了单例模式的基本原则。C++11引入了新的特性,如std::mutex和std::call_once,使得实现线程安全的单例模式变得...

    多线程单例模式并发访问

    总结起来,多线程环境下的单例模式实现需要注意线程安全问题,尤其是懒汉式单例,需要采取适当的同步措施来防止多线程环境下的实例化问题。此外,对于不同场景的需求,可以选择不同的实现方式来优化性能和资源使用。

    43丨单例模式(下):如何设计实现一个集群环境下的分布式单例模式?1

    传统的单例模式在多进程或多节点的分布式环境中不再适用,因为每个进程或节点都可以独立创建自己的单例实例。要实现分布式环境下的单例,可以采用以下策略: 1. **数据库锁**:在创建单例对象之前,所有节点尝试...

    Qt多工程调用单例实现,带线程锁

    在本文中,我们将深入探讨如何在Qt环境中使用多工程调用单例模式,并结合线程锁来确保数据管理的一致性...通过学习这个案例,开发者可以掌握如何在Qt中正确设计和使用单例模式,以及如何在多线程环境下保证数据一致性。

    QT单例模式、多线程、双重校验加锁

    在QT中,单例模式、多线程以及双重校验加锁(Double-Checked Locking)是常见的编程模式和技术,尤其在处理并发和资源管理时显得尤为重要。 **单例模式** 是一种设计模式,确保一个类只有一个实例,并提供一个全局...

    c++单例模式线程日志类

    在这个特定的场景中,我们讨论的是一个实现了单例模式的日志类,该类专为多线程环境设计,具备日志等级控制、精确的时间戳以及可变长参数和标准格式化输出的功能。 首先,让我们深入了解单例模式。单例模式的主要...

    浅议单例模式之线程安全(转)

    在多线程环境下,线程安全的单例模式尤为重要,因为如果不正确实现,可能会导致多个线程同时创建多个实例,违反了单例模式的基本原则。 在Java中,单例模式通常有以下几种实现方式: 1. 饿汉式(静态常量): ...

    线程安全的单例模式

    为了确保单例模式在多线程环境中的正确性,需要考虑如何使其具有线程安全性。 1. **同步方法**: ```java public final class ThreadSafeSingleton { private static ThreadSafeSingleton singObj = null; ...

    Java多线程实战之单例模式与多线程的实例详解

    延迟加载/懒汉模式是在调用方法时实例才被创建,在多线程环境下,会出现取出多个实例的情况,与单例模式的初衷是相背离的。如下代码所示: public class MyObject { private static MyObject myObject; private ...

    多线程并发下的单例模式-源码

    该资源是多线程并发下的单例模式-源码,几乎包含了所有方式实现的单例模式,并且能够确保在多线程并发下的线程安全性。 读者可结合本人博客 http://blog.csdn.net/cselmu9?viewmode=list 中的《线程并发之单例模式...

    设计模式之单例模式(结合工厂模式)

    在Java中,为了确保多线程环境下的正确性,我们可以使用synchronized关键字来保证同步,但这会引入性能开销。DCL模式通过在实例化单例时使用 volatile 关键字和双层检查,解决了这个问题。volatile关键字保证了多...

    Java 单例模式线程安全问题

    然而,在多线程环境下,单例模式可能会遇到线程安全问题,因为多个线程可能会同时访问同一个实例,从而导致数据不一致和其他问题。 在 Java 中,单例模式的实现可以使用双重检查锁机制、静态内部类和枚举类型等方式...

    设计模式——单例模式

    这里的 `getInstance()` 方法使用了 `synchronized` 关键字进行同步,保证了在多线程环境下的线程安全。但是,同步操作会降低性能,因为每次调用都需要进行锁的获取和释放。 为了解决懒汉式单例模式的性能问题,有...

    单例模式下,使用多线程实现

    在多线程环境下,单例模式的实现需要特别考虑线程安全问题。因为多个线程可能会同时尝试创建单例对象,如果没有正确的同步控制,就可能导致多个实例的产生,违反了单例模式的设计初衷。以下是一些在多线程环境中实现...

    C#单例模式详解 C#单例模式详解C#单例模式详解

    在C#中,单例模式常用于管理共享资源或控制类的实例化过程,以提高性能、节约系统资源,特别是在整个应用程序生命周期内只需要一个对象的情况下。 首先,实现C#单例模式通常有几种常见方法: 1. 饿汉式(静态常量...

    java单例模式实例

    在多线程环境下,可能会创建多个实例。例如: ```java public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == ...

    多线程下的单例模式优化

    这是一个关于多线程下的单例模式优化代码。public class Singleton { private static Singleton instance; private Singleton (){ } public static Singleton getInstance(){ //对获取实例的方法进行同步 if...

    单例模式详解~~单例模式详解~~

    这种方式虽然简单,但在多线程环境下可能存在问题,因为线程A和线程B可能会同时进入`if (instance == null)`的判断,导致创建多个实例。 为了解决这个问题,我们可以采用"双检锁/双重校验锁"(DCL,即Double-...

    7种单例模式

    下面将详细介绍七种常见的单例模式实现方式,并结合多线程环境和反序列化测试进行讨论。 1. **饿汉式单例**: 这是最简单的单例实现,它在类加载时就创建了实例,因此是线程安全的。 ```java public class ...

Global site tag (gtag.js) - Google Analytics