`
nianien
  • 浏览: 17490 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

非线程同步机制下线程安全的单例模式——最优的单例模式

阅读更多
个人认为下面是Java实现的最优的单例模式
这种实现方法采用内部静态类,
只在第一次调用getInstance方法的时候才实例化单例对象
如果不调用,就不会进行单例对象的实例化,
因此,既实现了延迟实例化,又不需要线程同步
引用

public class SingleTon {

private SingleTon(){}

public static SingleTon getInstance() {
return SingleTonHolder.instance;
}

private static class SingleTonHolder{
private static SingleTon instance=new SingleTon();
}
}



下面这种单例模式是应用最多的,同样不存在线程同步的问题
但是,不能实现延迟实例化
引用

public class SingleTon {

private SingleTon(){}
         private static SingleTon s=new SingleTon();

public static SingleTon getInstance() {
return s;
}

}



这种单例模式,和上面的实现差不多,虽然能够延迟单例对象的实例化,但是都是在同一时间范围内完成的
引用

public class SingleTon {

private SingleTon(){}
private static SingleTon s;

static {
s=new SingleTon();
}

public static SingleTon getInstance() {
return s;
}
}


下面这种就是


还有两种解决方案,不在本帖讨论范围之内
1.采用synchronized的关键字同步getInstance方法
2.采用synchronized的关键字同步代码段,双重是否为空的判断
分享到:
评论
14 楼 nianien 2011-05-18  
nianien 写道
个人认为下面是Java实现的最优的单例模式
这种实现方法采用内部静态类,
只在第一次调用getInstance方法的时候才实例化单例对象
如果不调用,就不会进行单例对象的实例化,
因此,既实现了延迟实例化,又不需要线程同步
引用

public class SingleTon {

private SingleTon(){}

public static SingleTon getInstance() {
return SingleTonHolder.instance;
}

private static class SingleTonHolder{
private static SingleTon instance=new SingleTon();
}
}



下面这种单例模式是应用最多的,同样不存在线程同步的问题
但是,不能实现延迟实例化
引用

public class SingleTon {

private SingleTon(){}
         private static SingleTon s=new SingleTon();

public static SingleTon getInstance() {
return s;
}

}



这种单例模式,和上面的实现差不多,虽然能够延迟单例对象的实例化,但是都是在同一时间范围内完成的
引用

public class SingleTon {

private SingleTon(){}
private static SingleTon s;

static {
s=new SingleTon();
}

public static SingleTon getInstance() {
return s;
}
}


下面这种就是


还有两种解决方案,不在本帖讨论范围之内
1.采用synchronized的关键字同步getInstance方法
2.采用synchronized的关键字同步代码段,双重是否为空的判断


下面是测试结果,以证明本人想法的正确性:
public class SingleTon {
    static {
            System.out.println("悲催了,被加载了!");
    }
    private SingleTon() {
        System.out.println("悲催了,被实例化了!");
    }

    public static SingleTon getInstance() {
        return SingleTonHolder.instance;
    }

     public static void otherMethod() {
         System.out.println("悲催了,调用其他方法了!");
    }
    private static class SingleTonHolder {
        private static SingleTon instance = new SingleTon();
    }

 }


public class Test {

    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("com.lining.SingleTon");
        SingleTon.otherMethod();
        SingleTon.getInstance();     
    }
}


output:
悲催了,被加载了!
悲催了,调用其他方法了!
悲催了,被实例化了!
13 楼 zhang34082 2011-05-18  
nianien 写道
zhang34082 写道
nianien 写道

zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的"



怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的


类加载的时候,对于静态变量与块,从上而下逐个执行。延迟加载是用的时候才实例化。
public static void main(String[] args) {
       
        SingleTon  instance = SingleTon .getInstance();// 在这个地方设断点
    }
可以通过这个在测试。是否是延迟加载的

public class SingleTon {

private SingleTon(){}

public static SingleTon getInstance() {
return SingleTonHolder.instance;
}

static class SingleTonHolder{
private static SingleTon instance=new SingleTon();
}
}
你敢实际测试一下么?
你不调用,它会实例化?

多的俺不说了,如果你觉得他是延迟加载的,你提供测试方法出来,或者说下静态类、嵌套类中静态实例在类加载的时候是怎么加载的
12 楼 nianien 2011-05-18  
zhang34082 写道
nianien 写道

zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的"



怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的


类加载的时候,对于静态变量与块,从上而下逐个执行。延迟加载是用的时候才实例化。
public static void main(String[] args) {
       
        SingleTon  instance = SingleTon .getInstance();// 在这个地方设断点
    }
可以通过这个在测试。是否是延迟加载的

public class SingleTon {

private SingleTon(){}

public static SingleTon getInstance() {
return SingleTonHolder.instance;
}

static class SingleTonHolder{
private static SingleTon instance=new SingleTon();
}
}
你敢实际测试一下么?
你不调用,它会实例化?



11 楼 zhang34082 2011-05-18  
zhang34082 写道
littcai 写道
第一种是延迟加载的,优

不是延迟加载的,都是类加载的时候 初始化实例变量的,没区别


在类加载的时候,静态变量与静态块 从上而下逐个执行的。
10 楼 zhang34082 2011-05-18  
nianien 写道

zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的"



怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的


类加载的时候,对于静态变量与块,从上而下逐个执行。延迟加载是用的时候才实例化。
public static void main(String[] args) {
       
        SingleTon  instance = SingleTon .getInstance();// 在这个地方设断点
    }
可以通过这个在测试。是否是延迟加载的
9 楼 zhang34082 2011-05-18  
littcai 写道
第一种是延迟加载的,优

不是延迟加载的,都是类加载的时候 初始化实例变量的,没区别
8 楼 nianien 2011-05-18  
zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的

怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的
7 楼 zhang34082 2011-05-18  
第三种与第一种 是一样的机制,都是通过静态块来初始化的,都是类加载的时候初始化的
第一种与第二种区别也不大,同样是类加载的时候初始化的
6 楼 Technoboy 2011-05-18  
nianien 写道
littcai 写道
第一种是延迟加载的,优

从多线程的角度考虑,会不会有并发问题呢?

不会!
5 楼 nianien 2011-05-18  
除却线程同步的方法,这三种单例模式之外,还有其他方法么?

个人认为第三种方法兼具了一次实例化和延迟加载的有点,最完美的实现方式
4 楼 nianien 2011-05-18  
twojinyong 写道
明明有三种方式。。。。

除了我说的这三种,你的第三种应该是第四种吧?双锁机制?
3 楼 twojinyong 2011-05-18  
明明有三种方式。。。。
2 楼 nianien 2011-05-18  
littcai 写道
第一种是延迟加载的,优

从多线程的角度考虑,会不会有并发问题呢?
1 楼 littcai 2011-05-18  
第一种是延迟加载的,优

相关推荐

    设计模式——单例模式

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

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

    总的来说,单例模式是一种常见的设计模式,懒汉式单例模式则是其中一种实现策略,它的主要特点是延迟加载和线程安全。在选择单例模式实现时,开发者需要根据具体需求考虑性能、线程安全以及代码简洁性等因素。

    三种工厂设计模式和两种单例模式

    在本文中,我们将深入探讨三种工厂设计模式——简单工厂模式、抽象工厂模式和工厂方法模式,以及两种单例模式——饿汉单例模式和懒汉单例模式。这些模式都是面向对象设计中的重要组成部分,对于理解和构建可维护、可...

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

    非线程安全的懒汉模式代码如下: ```java public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { ...

    python 线程同步机制(csdn)————程序.pdf

    Python中的线程同步机制是为了在多线程环境中确保对共享资源的有序访问,避免出现竞态条件和数据不一致的情况。在上述例子中,我们看到了一个典型的线程同步问题及其解决方案。 首先,让我们理解什么是线程竞态条件...

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

    这种同步的懒汉式虽然保证了线程安全,但在多线程环境下,每次获取实例都需要进行同步,性能会受到影响。 为了兼顾线程安全和性能,可以采用双检锁/双重校验锁(Double-Check Locking,DCL)的懒汉式单例: ```...

    单例模式应用场景

    文件系统本质上是一个大型的单例模式实现,确保了所有文件操作都在同一套规则下执行,从而保障了数据的完整性和安全性。 **9. HttpApplication** 在ASP.NET框架中,HttpApplication作为HTTP请求处理流程的核心组件...

    设计模式-单例模式

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

    C#多线程与线程同步机制高级实战课程

    视频课程下载——C#多线程与线程同步机制高级实战课程

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

    为了使"懒汉式"单例在多线程环境下安全,可以使用synchronized关键字来同步方法: ```java public class Singleton { private static Singleton instance; private Singleton() {} public synchronized static ...

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

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

    单例 模式 singleton

    另一种线程安全且高效的单例实现方式是利用Java类加载机制,将实例的创建推迟到类加载时: ```java public class SingletonClass { private SingletonClass() {} private static class SingletonHolder { ...

    Java 单例模式——漂亮学姐要我电话号码干什么?这么关心我难道她想……让你以最难忘的例子认识单例模式!!!

    然而,普通的懒汉式单例在多线程环境下可能存在线程安全问题,即多个线程可能同时进入`if (null == beautifulSister)`判断并创建多个实例。 为了解决这个问题,可以使用双重检查锁定(Double-Checked Locking)来...

    工厂模式与单例模式

    在上述代码中,`getInstance()`方法使用了双重检查锁定,既保证了线程安全,又避免了不必要的同步开销。 结合工厂模式和单例模式,我们可以设计出更复杂的应用架构。例如,一个系统中可能有多个单例对象,每个对象...

    单例模式的几种实现方式

    4. 懒汉式(线程安全——同步方法) 通过同步关键字`synchronized`保证线程安全,但每次获取实例时都需要进行同步操作,性能较低。 ```java public class Singleton { private static Singleton instance; ...

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

    在这个例子中,`volatile`关键字确保了多线程环境下的可见性和有序性,`synchronized`关键字确保了线程安全,避免了多个线程同时创建单例对象。 接下来,我们转向“装饰模式”。装饰模式是一种结构型设计模式,它...

    操作系统实验报告——线程与进程同步

    实验内容集中在Linux下的多线程同步机制上,具体通过修改生产者-消费者问题的示例程序来实现。在这个问题中,多个生产者线程生成数据,而消费者线程负责消费这些数据。为了保证数据的一致性和正确性,需要防止多个...

    java设计模式——单例模式

    【Java设计模式——单例模式】 单例模式是一种常见的软件设计模式,它的核心思想是确保在应用程序的整个生命周期中,某个类只有一个实例存在。这种模式主要用于控制类的实例化过程,减少系统资源的消耗,提高系统...

Global site tag (gtag.js) - Google Analytics