0 0

关于单例模式线程安全问题10

很多地方都出现过这样的说法,单例模式要注意线程安全,就是要在取实例的操作上加入同步锁,比如
public xxx getInstance sync……(){
return instance;
}

首先,为什么要同步,不同步出现错误的时机是什么?
还有,单例模式有懒汉式和非懒汉式,如果是懒汉式是否需要加同步锁,非懒汉式呢,我个人对很多人说单例模式要注意线程安全有点迷惑,感觉大多数时候都没有必要。首先因为我很排斥同步锁,有时甚至宁可冒多线程出错的风险也不想加锁。这里抛砖引玉,看大家的想法。
问题补充
其实对于懒汉式来说,应该可以不用注意多线程方面的问题的,这是我的一个意思,还有一个意思是,对于非懒汉式,我觉的,在有些方面(这种情况很多)我们用伪单例模式可能更合适,我这里的伪单例模式是在大多数情况下只有一个实例,但是在某些特殊的情况下,比如高度并发的情况下,我们应该允许他出现多个实例来满足实际的需要,当然,我们要保证业务逻辑不会出错,但没必要达到真正意义上的单例模式,单例模式的作用有一方面就是为了节省资源,提高速度,但为了绝对意义上的单例,我们去加个同步锁,感觉有点得不尝失。当然,前提是出现伪单例不会影响到业务逻辑。
2009年4月15日 13:03

4个答案 按时间排序 按投票排序

0 0

直接接楼上的话

对于同步问题,只有存在共享数据会修改的情况下才会出现。  

而使用单例模式的一个主要出发点:
1. 全局单例。  这就涉及访问共享资源的安全问题。  对于一般而言 。在这种操作上都采取互斥锁来保证共享数据的安全性 。 但这样是以失去性能为代价。  而更高级点的。采用TM模式或者共享锁来实现性能的提升。 但这样带来的是复杂度的上升。
2. 性能:  对于一些需要频繁创建且内容基本相同变化较少的实例。 如Spring 的上下文环境 。  一些配置文件信息等。  避免每次重复加载配置信息而造成资源 性能 的浪费。可以使用单例模式 。


个人理解 ,欢迎指出不全之处

2009年4月15日 18:22
0 0

[url]首先,为什么要同步,不同步出现错误的时机是什么? [/url]
比如可能会出现脏读,比如一个线程正在修改数据,另外一个线程读数据,他读完后值被修改了,就读到了错误的数据。


懒汉这个东西用不用都行,如果创建对象的开销比较大,用的情况不多的化就懒汉

如果性能要求高,就直接创建别懒汉了

2009年4月15日 14:24
0 0

模式一:
class Singleton2 {

private Singleton2(){
}

private static Singleton2 instance;

public synchronized static Singleton2 getInstance() {

  if(instance==null)
//这种情况是加了同步,这样,多个线程就没有办法同时到达这个位置
{
   instance=new Singleton2();
  }
  return instance;
}

}

class Singleton2 {

private Singleton2(){
}

private static Singleton2 instance;

public static Singleton2 getInstance() {

  if(instance==null)
//这种情况是没有加同步,这样两个线程就无限制的进到这个位置,自然两个线程如果同时到达这里,都执行判断instance==null为true,
就可以进入去执行instance=new Singleton2();,这时就new了两个对象出来,因为都是赋给instance,自然有一个被后面new的覆盖,当然内存中就有一个垃圾对象了,
{
   instance=new Singleton2();
  }
  return instance;
}

}
不用说,大家也知道,这种在单线程程序中是没什么问题的,但多线程程序中,则可能会创建出2个或多个对象.

模式二:

public class Singleton {

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

public static Singleton getInstance(){
  return instance;
}

}
这种很显然没有前者的问题,也是值得推崇的方式.

模式三:

public class Singleton {

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

public static Singleton getInstance() {
  return SingletonHolder.instance;
}

}

2009年4月15日 13:32
0 0

不同步的话, 对于懒汉式的, 就是在, 这个类的实例还没有创建的时候, 2个线程同时去调用getInstance, 这时, 由于没有同步锁, 有可能会创建出2个实例来。
对于饿汉式, 由于实例是在load class的时候创建的, 所以就没有这个问题。 当然, 就是2个线程采用了不同的class loader.
当然, 无论饿汉还是懒汉, 几率都不高, 但几率低不代表不会出错, 逻辑上也不对, 因此, 编程者还是应该避免。

2009年4月15日 13:03

相关推荐

    Java 单例模式线程安全问题

    Java 单例模式线程安全问题详解 Java 单例模式线程安全问题是指在 Java 中实现单例模式时,如何确保线程安全的问题。单例模式是指在整个应用程序生命周期中,只有一个实例存在的设计模式。这种模式可以提高性能,...

    Java中懒汉单例设计模式线程安全测试

    Java中懒汉单例设计模式线程安全测试,单例设计模式的测试

    线程安全的单例模式

    ### 线程安全的单例模式详解 #### 一、单例模式简介 单例模式(Singleton Pattern)是软件开发中最常用的创建型设计模式之一,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点。单例模式在很多场景下...

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

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

    单例模式线程安全的三种表达

    单例模式三种线程安全的表达方式,其中枚举方式的单例是最安全的

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

    在C++编程中,单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在这个特定的场景中,我们讨论的是一个实现了单例模式的日志类,该类专为多线程环境设计,具备日志等级控制、...

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

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

    C++两种线程安全的单例模式的实现

    使用"懒汉模式"与"饿汉模式"实现c++的单例模式,并且确保了单例模式的第一次实例化的线程安全,以及程序结束时,单例对象的资源收回,以防内存资源的泄漏

    synchronized与单例的线程安全

    "synchronized"关键字和单例模式是确保线程安全的两种常见手段。本文将详细探讨这两个概念及其在实现线程安全中的作用。 一、synchronized关键字 synchronized是Java中的一个关键同步机制,用于控制对类或对象的...

    单例模式单例模式单例模式

    - **并发问题**:在多线程环境中,单例模式可能会导致线程安全问题,需要额外处理同步机制。 #### 五、实例解析 在给定的内容中提到的`Martin`类就是一个典型的单例模式实现案例。它通过将构造器私有化以及提供一...

    多线程单例模式并发访问

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

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

    在Java中,实现单例模式有多种方式,但最常见的问题是线程安全问题。例如,上述代码展示了一个简单的单例实现,称为"饿汉式"单例,因为无论是否需要,它都会在类加载时立即创建实例。这种方式虽然简单,但在多线程...

    7种单例模式

    为解决线程安全问题,可以将 `getInstance` 方法声明为同步的,但这会降低效率。 ```java public class Singleton { private static Singleton instance; private Singleton() {} public synchronized static ...

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

    单例模式是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在C#中,单例模式常用于管理共享资源或控制类的实例化过程,以提高性能、节约系统资源,特别是在整个应用程序生命周期内只需要一...

    详解python实现线程安全的单例模式

    然而,如果我们想要在类级别实现线程安全的单例模式,就需要考虑多线程环境下的并发问题。 在给出的代码中,首先定义了一个装饰器`Singleton`,它的目的是确保每次调用时返回的是同一个实例。装饰器内部维护了一个...

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

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

    Qt两种方法实现多线程并安全结束线程及QMutex加锁Qt单例化实现

    本主题将详细探讨如何使用Qt的QThread类来创建和管理线程,并且安全地结束线程,同时结合QMutex进行线程同步,以及如何实现Qt的单例模式。 1. **QThread的使用**: - **创建线程**: 在Qt中,创建线程通常是通过...

    java单例模式实例

    为了解决懒汉式的线程安全问题,我们引入**饿汉式(Eager Initialization)**。在类加载时就创建单例对象,因此是线程安全的,但可能导致不必要的内存占用。代码如下: ```java public class Singleton { private ...

    Java设计模式之单例模式的七种写法

    这种写法的问题是它没有考虑线程安全问题,在并发环境下很可能出现多个 Singleton1 实例。 2、懒汉式单例(加同步) public class Singleton2 { private Singleton2() {} private static Singleton2 single = ...

    设计模式——单例模式

    以上就是关于单例模式的一些核心概念和常见实现方式。在实际开发中,根据需求和场景选择合适的实现方式至关重要,以平衡性能和资源使用。同时,需要注意的是,过度依赖单例可能导致系统设计过于紧密,不利于测试和...

Global site tag (gtag.js) - Google Analytics