0 0

java单例模式的线程安全问题10

最近在学习设计模式,在看到单例时突然想到如果在多线程的情况下会导致出错(多个线程同时进行操作)。因此赶紧放狗去搜。终于找到了一段据说可以实现线程安全的单例程序。我把它贴出来,希望有人能解答我的疑惑。

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 final class EagerSingleton
{
    private static EagerSingleton singObj = new EagerSingleton();

    private EagerSingleton()
    {
    }

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


比较明显,这种是线程安全的。因为static变量是在类被加载时(有可能没被实例化)初始化并仅被初始化一次。因为这样就可以保证只有一个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()时则可能会生成多个实例。因此才需要修改一下。修改为我之前的那段代码
package net.chopsuey.singleton;  
 
public class Singleton  
{  
    private static class SingletonHolder  
    {  
        static Singleton instance = new Singleton();  
    }  
 
    public static Singleton getInstance()  
    {  
        return SingletonHolder.instance;  
    }  
}

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

如果有什么不同意见的话,欢迎各位继续提出!
2009年3月04日 12:42

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

0 0



你的主题应该改为 怎样在多线程的情况下得到单例。
你的三个方法都可以做到

引用
1:

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


2:
package net.chopsuey.singleton;  
 
public final class EagerSingleton  
{  
    private static EagerSingleton singObj = new EagerSingleton();  
 
    private EagerSingleton()  
    {  
    }  
 
    public static EagerSingleton getSingleInstance()  
    {  
        return singObj;  
    }  

3:

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;  
    } 



你的主题
引用
java单例模式的线程安全问题

你想想。多个线程拿到了同一个实例。那这个实例还安全吗??
所以你应该在多个线程只有一个线程拿到了这个实例。所以你要加锁
如它
引用
public class Singleton(){
     private volatile static Singleton singleton;
     private Sington(){};
     public static Singleton getInstance(){
     if(singleton == null){
         synchronized (Singleton.class);
              if(singleton == null){
                 singleton = new Singleton();
                                   }
                          }
              }
return singleton;
        }
}






2009年3月04日 14:11
0 0

在用单例时加锁就行了啊。
你说的代码

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

是线程安全的吗??我看不是线程安全的。如果多个线程去调用。得到的还不是一个实例。有没有加锁。肯定不安全。

引用
public class Singleton(){
     private volatile static Singleton singleton;
     private Sington(){};
     public static Singleton getInstance(){
     if(singleton == null){
         synchronized (Singleton.class);
              if(singleton == null){
                 singleton = new Singleton();
                                   }
                          }
              }
return singleton;
        }
}


这个加锁了。它才是线程安全的

2009年3月04日 13:18
0 0

public class Singleton(){
     private volatile static Singleton singleton;
     private Sington(){};
     public static Singleton getInstance(){
     if(singleton == null){
         synchronized (Singleton.class);
              if(singleton == null){
                 singleton = new Singleton();
                                   }
                          }
              }
return singleton;
        }
}

volatile在jdk 1.5以上才能使用---代码源于《head first设计模式》
http://www.blogjava.net/duduli/archive/2008/11/22/241945.html

2009年3月04日 12:42

相关推荐

    Java 单例模式线程安全问题

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

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

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

    java单例模式实例

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

    Java 单例模式.pptx

    - **线程安全问题**:懒汉式单例模式在多线程环境下可能会导致创建多个实例,因此需要采用同步机制保证线程安全,例如使用`synchronized`关键字。 - **静态内部类方式** - **实现**: ```java class Single3 {...

    线程安全的单例模式

    然而,这种方式存在线程安全问题,当多个线程几乎同时调用 `getSingleInstance()` 方法并判断 `singObj` 为空时,会导致多次实例化。 #### 三、线程安全的单例实现方式 为了确保单例模式在多线程环境中的正确性,...

    Java 单例模式 工具类

    Java中的单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供全局访问点。在Java编程中,单例模式常用于控制资源的访问,比如数据库连接池、线程池或者日志对象等。本篇文章将深入探讨如何在Java中...

    深入Java单例模式浅析

    但在多线程环境下,如果没有同步控制,可能存在线程安全问题。如下所示: ```java public class SingletonClass { private static SingletonClass instance = null; public static SingletonClass getInstance()...

    Java 单例模式 懒汉模式

    Java 单例模式 懒汉模式 //懒汉式 多线程中不可以保证是一个对象

    使用Java单例模式实现一个简单的日志记录器.txt

    ### 使用Java单例模式实现一个简单的日志记录器 #### 一、单例模式简介 单例模式是一种常用的软件设计模式,在该模式中,一个类只能创建一个实例,并且提供了一个全局访问点来访问该实例。单例模式的主要优点包括...

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

    在懒汉式的基础上添加了同步锁,避免了线程安全问题。 ```java public class Singleton { private volatile static Singleton INSTANCE; private Singleton() {} public static Singleton getInstance() {...

    Java单例模式设计

    Java单例模式是一种常用的设计模式,它保证一个类只有一个实例,并提供全局访问点。这种模式在需要频繁创建和销毁对象的场景中,或者当对象昂贵时(如数据库连接),能够节省系统资源,提高效率。本篇文章将深入探讨...

    Java单例模式深入理解

    Java单例模式是一种设计模式,它允许在程序中创建唯一一个类实例,通常用于管理共享资源,例如数据库连接、线程池或者配置对象等。单例模式的核心在于限制类的构造函数,确保类只能被初始化一次,从而实现全局唯一的...

    Java实现多种单例模式

    这种方法在多线程环境中存在线程安全问题,如果不加同步控制,可能会创建多个实例。 ```java public class SingleInstance1 { private static SingleInstance1 instance; private SingleInstance1() {} public...

    JAVA单例模式的几种实现方法

    ### JAVA单例模式的几种实现方法 #### 一、饿汉式单例类 饿汉式单例类是在类初始化时就已经完成了实例化的操作。这种实现方式简单且线程安全,因为实例化过程是在编译期间完成的,不会受到多线程的影响。 **代码...

    Java单例模式应用研究.pdf

    ### Java单例模式应用研究 #### 一、单例模式概述 单例模式(Singleton Pattern)作为一种最基本的创建型设计模式,其主要目的是控制一个类的实例化过程,确保在整个应用程序中仅存在一个实例,并且该实例能够被全局...

    java单例模式的例子

    Java单例模式是一种常见的设计模式,它在软件工程中用于控制类的实例化过程,确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统资源管理、缓存、日志记录等方面应用广泛。下面我们将深入探讨Java单例...

    java单例模式连接数据库源码

    Java单例模式是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在数据库连接管理中,使用单例模式能有效控制资源,避免频繁创建和关闭数据库连接导致的性能损失和资源浪费。以下是对Java单例模式...

    java设计模式之单例模式.zip

    1. **饿汉式(静态常量)**:在类加载时就完成了初始化,所以没有线程安全问题,但这种实现方式无法实现延迟加载。 ```java public class Singleton { private static final Singleton INSTANCE = new Singleton...

Global site tag (gtag.js) - Google Analytics