浅议单例模式之线程安全
使用单例模式有什么注意事项

使用单例模式有什么注意事项使用单例模式时需要注意以下几个方面:
1. 线程安全,在多线程环境下,需要考虑单例对象的线程安全性。
如果多个线程同时访问并且会修改单例对象,就需要确保线程
安全,可以通过加锁的方式来实现线程安全的单例模式。
2. 延迟加载,有时候希望在需要的时候才创建单例对象,这就
需要注意延迟加载的问题。
在使用懒汉式单例模式时,需要考虑线
程安全性和性能问题。
3. 序列化与反序列化,在使用单例模式时,需要考虑对象的序
列化与反序列化。
因为在反序列化时,会创建新的对象,可能破坏
单例模式的初衷。
可以通过重写readResolve方法来解决这个问题。
4. 内存泄漏,如果单例对象长时间持有外部资源,容易导致内
存泄漏问题,需要特别注意单例对象的生命周期管理。
5. 测试困难,由于单例对象的全局访问性,可能会导致测试困难。
因为单例对象在测试时可能会影响其他模块的测试结果,需要
特别注意测试用例的编写。
6. 可维护性,单例模式可能会导致代码的耦合性增加,降低了代码的灵活性和可维护性,需要慎重考虑是否真的需要使用单例模式。
综上所述,使用单例模式时需要考虑线程安全、延迟加载、序列化与反序列化、内存泄漏、测试困难和可维护性等问题,需要根据具体的业务场景和需求来综合考虑,确保单例模式的正确性和合理性。
线程同步、线程安全的单例模式

线程同步、线程安全的单例模式1.线程同步就是指多个线程同时轮流抢占CPU资源,但可能会造成数据的错误1)当某⼀个CPU资源为共享时,将其定义为static类型,类变量,全类都可以访问,为共享资源准备2)当线程⼀起争夺CPU资源时,CPU资源被声明为static类时,线程⾥⾯的内容会因为线程的休眠被最后⼀个线程覆盖3)线程同步可以解决这个问题,通过synchronized关键字修饰共享资源⽅法,相当于给在运⾏的线程上⼀把内置锁只有当它运⾏完后,才会允许其他线程争夺之后循环这个操作4 )线程同步还可以锁定代码块,就是线程们共享的资源,这个时候需要通过synchronized关键字锁住他们共处的类,并加上.class来标识2.如何判断线程是同步还是不同步?看他们锁定的资源时⼀份还是多份,⼀份就是同步,多份就是不同步3.本质上,⽆论是锁定类还是⽅法,主要看他是不是独⼀⽆⼆的,也就是说看他是不是⼀份,例如类是⼀个,⽅法很多⽅法是静态那么就独此⼀份,⾮静态就是多份4.单例模式就是⼀个类只有⼀个对象主要分三种情况1)第⼀种:单线程的单例模式创建⼀个类⽤于线程对共享资源的抢占,该类将对象声明私有,创建⼀个公共⽅法来创建对象再创建⼀个测试类来创建实例对象public class SingleThread1{private static SingleThread singleThread;public SingleThread(){System.out.println("创建了SingleThread对象!");}public static synchronized SingleThread getsingleThread(){if(singleThread==null){singleThread = new SingleThread();}return singlrThread;}}public class Test{public static void main(String []args){SingleThread singleThread = SingleThread.getsingleThread();}}2)第⼆种:多线程的单例模式测试类⾥⾯通过匿名类创建两个线程⽤于对共享资源类的竞争来体现单例public class SingleThread1{private static SingleThread singleThread;public SingleThread(){System.out.println("创建了SingleThread对象!");}public static synchronized SingleThread getsingleThread(){if(singleThread==null){singleThread = new SingleThread();}return singlrThread;}}public class test1{public static void main(String []args){new Thread(new Runnable(){@Overridepublic void run(){SingleThread singleThread1 = SingleThread.getsingleThread();}}).start();new Thread(new Runnable(){@Overridepublic void run(){SingleThread singleThread2 = SingleThread.getsingleThread();}}).start();}}第三种锁定共享代码块,双层检测⽆需将公共使⽤的整个⽅法都锁住,只需要锁住他们共享资源代码块也是⼀样的效果,⽽且这样更有效public class SingleThread{private static SingleThread singleThread;public SingleThread(){System.out.println("创建了SingleThread对象");public static SingleThread getsingleThread(){if(singleThread == null){synchronized(SingleThread.class){if(singleThread == null){singleThread = new SingleThread();}}}return singleThread;}}}public class test1{public static void main(String []args){new Thread(new Runnable(){@Overridepublic void run(){SingleThread singleThread1 = SingleThread.getsingleThread();}}).start();new Thread(new Runnable(){@Overridepublic void run(){SingleThread singleThread2 = SingleThread.getsingleThread();}}).start();}}总结:可能⼏天没有看java,有些东西有些忘咯,今天所学的知识还是有些没有捋清楚线程同步。
Java设计模式之线程安全单例模式的实现和应用场景

Java设计模式之线程安全单例模式的实现和应⽤场景java中单例模式是⼀种常见的设计模式,单例模式的写法有好⼏种,这⾥主要介绍四种:懒汉式单例、饿汉式单例、双重锁检查、登记式单例。
单例模式有以下特点: 1、单例类只能有⼀个实例。
2、单例类必须⾃⼰创建⾃⼰的唯⼀实例。
3、单例类必须给所有其他对象提供这⼀实例。
单例模式确保某个类只有⼀个实例,⽽且⾃⾏实例化并向整个系统提供这个实例。
所谓单例,指的就是单实例,有且仅有⼀个类实例,这个单例不应该由⼈来控制,⽽应该由代码来限制,强制单例。
单例有其独有的使⽤场景,⼀般是对于那些业务逻辑上限定不能多例只能单例的情况,例如:类似于计数器之类的存在,⼀般都需要使⽤⼀个实例来进⾏记录,若多例计数则会不准确。
适合应⽤场景需要频繁的进⾏创建和销毁的对象;创建对象时耗时过多或耗费资源过多,但⼜经常⽤到的对象;⼯具类对象;频繁访问数据库或⽂件的对象。
在Spring中创建的Bean实例默认都是单例模式存在的。
单例优点系统内存中该类只存在⼀个对象,节省了系统资源,对于⼀些需要频繁创建销毁的对象,使⽤单例模式可以提⾼系统性能。
由于单例模式在内存中只有⼀个实例,减少了内存开销。
单例模式可以避免对资源的多重占⽤,例如⼀个写⽂件时,由于只有⼀个实例存在内存中,避免对同⼀个资源⽂件的同时写操作。
单例模式可以再系统设置全局的访问点,优化和共享资源访问。
其中使⽤到单例模式时,考虑较多的就是多线程的情况下如何防⽌被多线程同时创建等问题,其中《Head First Design Patterns》使⽤到“double-checked locking”来降低使⽤synchronization。
当这个类的对象在多个地⽅创建的时候,使得内部的⽅法多次调⽤,但是希望只要⼀个对象操作这个⽅法,或者不希望多个地⽅同时调⽤这个⽅法,需要保持这个⽅法的单⼀性质,就⽤单利模式单例缺点当想实例化⼀个单例类的时候,必须要记住使⽤相应的获取对象的⽅法,⽽不是使⽤new,可能会给其他开发⼈员造成困扰,特别是看不到源码的时候。
使用单例模式有什么注意事项

使用单例模式有什么注意事项使用单例模式时需要注意以下几个事项:
1. 线程安全,在多线程环境下,需要确保单例对象的创建是线
程安全的。
可以使用双重检查锁定(double-checked locking)或
者静态内部类的方式来保证线程安全。
2. 垃圾回收,在某些情况下,单例对象可能会一直存在于内存
中而无法被垃圾回收。
因此需要注意单例对象的生命周期,避免出
现内存泄漏。
3. 序列化与反序列化,当单例类需要支持序列化和反序列化时,需要特别小心。
需要实现特殊的readResolve()方法来确保反序列
化时返回的仍然是单例对象。
4. 类加载器,在某些情况下,不同的类加载器可能会导致多个
单例实例被创建。
因此需要确保单例对象在不同的类加载器环境下
仍然是唯一的。
5. 内存占用,单例对象一直存在于内存中,可能会占用较大的
内存空间。
需要评估单例对象的大小以及应用程序的内存限制,避免造成内存浪费。
6. 测试,单例模式在测试时可能会带来一些困难,因为单例对象的状态在不同的测试用例之间可能会有影响。
需要特别小心设计测试用例,确保单例对象的状态不会相互干扰。
总之,使用单例模式需要注意线程安全、垃圾回收、序列化与反序列化、类加载器、内存占用以及测试等方面的问题,以确保单例对象的正确性和可靠性。
springboot单例模式与线程安全

springboot单例模式与线程安全在Spring Boot中,单例模式和线程安全是两个非常重要的概念。
本文将分别介绍单例模式和线程安全,并讨论如何在Spring Boot应用中确保单例模式的线程安全性。
首先,单例模式是一种设计模式,它确保一个类只有一个实例,并提供全局访问点。
在Spring Boot应用中,单例模式可以用于管理共享资源,如数据库连接、线程池等。
通过将对象的实例化过程封装在一个私有的构造方法中,并提供一个静态方法返回实例,可以确保该类只有一个实例。
实现单例模式有多种方式,下面介绍两种常用的方式。
1.饿汉式单例模式:在类加载时就创建实例,并通过静态方法返回实例。
```public class Singletonprivate static final Singleton INSTANCE = new Singleton(;private Singleton( {}public static Singleton getInstancreturn INSTANCE;}```2.懒汉式单例模式:在首次调用时才创建实例,并通过双重检查锁定保证线程安全。
```public class Singletonprivate static volatile Singleton instance;private Singleton( {}public static Singleton getInstancif (instance == null)synchronized (Singleton.class)if (instance == null)instance = new Singleton(;}}}return instance;}```上面的两种方式都可以实现单例模式,但是在多线程环境下,需要考虑线程安全问题。
如果多个线程同时调用getInstance(方法,可能会导致创建多个实例。
为了保证线程安全,可以使用volatile关键字和双重检查锁定机制。
Spring单例和线程安全、ThreadLocal

Spring单例和线程安全、ThreadLocalSpring框架中的bean 或者说组件,默认是单例的。
单例模式确保了某个类只有⼀个实例,并且⾃⾏实例化,向整个系统提供这个实例。
在多线程的情况下,Web容器会向每个请求分配⼀个线程。
这些线程会执⾏对应的业务逻辑。
如果在执⾏的时候对单例对象进⾏了修改,则必须考虑到线程同步的问题。
同步机制ThreadLocal 和 线程同步机制 线程同步机制中,通过对象的锁机制保证同⼀时间只有⼀个线程访问变量。
这时该变量是多个线程共享的,使⽤同步机制要求程序慎密地分析什么时候对变量进⾏读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题。
ThreadLocal会为每⼀个线程提供⼀个独⽴的变量副本,从⽽隔离了多个线程对数据的访问冲突。
因为每⼀个线程都拥有⾃⼰的变量副本,从⽽也就没有必要对该变量进⾏同步了。
ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
对于多线程资源共享的问题,同步机制采⽤了“以时间换空间”的⽅式,⽽ThreadLocal采⽤了“以空间换时间”的⽅式。
前者仅提供⼀份变量,让不同的线程排队访问,⽽后者为每⼀个线程都提供了⼀份变量,因此可以同时访问⽽互不影响。
在spring 中是使⽤ ThreadLocal 解决线程安全问题线程安全问题主要是全局变量和静态变量引起的。
若每个线程中对全局变量、静态变量读操作,⽽⽆写操作,⼀般来说这个全局变量是线程安全的。
若多个线程同时执⾏写操作,需要考虑线程同步问题,否则影响线程安全。
spring 使⽤ThreadLocal 实现⾼并发下 共享资源的同步。
原理: 为每⼀个使⽤该变量的线程都提供⼀个变量值的副本,是每⼀个线程都可以独⽴地改变⾃⼰的副本,⽽不会和其它线程的副本冲突。
从线程的⾓度看,就好像每⼀个线程都完全拥有该变量。
【每个线程其实是改变的是⾃⼰线程的副本,⽽不是真正要改变的变量,所以效果就是每个线程都有⾃⼰的,“这其实就将共享变相为⼈⼈有份!”】ThreadLocal 如何实现为每⼀个变量维护变量的副本。
使用Swift线程安全地进行单例模式的设计
使用Swift线程安全地进行单例模式的设计在开发iOS应用程序时,经常会使用单例模式来确保一个类只有一个实例对象,并且该实例可以在整个应用程序中被访问。
然而,在多线程环境下使用单例模式可能会导致线程安全问题,因此需要采取一些措施来保证单例对象的线程安全。
本文将介绍如何使用Swift语言来线程安全地进行单例模式的设计。
一、什么是单例模式单例模式是一种创建型设计模式,它确保一个类只有一个实例,并且提供一个全局的访问入口。
在整个应用程序中,无论何时何地需要使用该类的实例,都可以通过该访问入口获得。
这种设计模式在很多情况下非常有用,例如管理应用程序的配置信息、全局共享的资源等。
二、常用的单例模式实现在Swift语言中,有几种常用的单例模式实现方式,包括懒加载式、静态常量式和dispatch_once式。
在这些方式中,懒加载式是最常见和推荐的一种实现方式,它可以在需要使用时才创建单例对象,避免了不必要的资源浪费。
下面我们将以懒加载式单例模式为例,介绍如何在Swift语言中线程安全地设计单例模式。
```swiftclass Singleton {static let sharedInstance = Singleton()private init() {}}```在上述代码中,我们通过静态常量的形式创建了一个单例对象sharedInstance,并将其限定为只能在Singleton类内部访问。
接下来,我们将介绍如何在这个基础上实现线程安全。
三、使用互斥锁实现线程安全在多线程环境下,当多个线程同时尝试创建单例对象时,可能会导致多个实例被创建出来。
为了避免这种情况,我们需要使用互斥锁来确保在任意时间只有一个线程可以创建对象。
在Swift语言中,我们可以使用GCD(Grand Central Dispatch)提供的信号量来实现互斥锁。
下面是线程安全的懒加载式单例模式的实现代码:```swiftclass Singleton {static let sharedInstance: Singleton = {let instance = Singleton()return instance}()private init() {}}```在上述代码中,我们使用了一个闭包来延迟初始化sharedInstance,并且利用GCD的信号量实现了互斥锁。
iOS单例模式线程安全问题
iOS单例模式线程安全问题 #import "DemoObj.h"@implementation DemoObjstatic DemoObj *instance;/**1. 重写allocWithZone,⽤dispatch_once实例化⼀个静态变量2. 写⼀个+sharedXXX⽅便其他类调⽤*/// 在iOS中,所有对象的内存空间的分配,最终都会调⽤allocWithZone⽅法// 如果要做单例,需要重写此⽅法// GCD提供了⼀个⽅法,专门⽤来创建单例的1 + (id)allocWithZone:(struct _NSZone *)zone23 {45static DemoObj *instance;6789// dispatch_once是线程安全的,onceToken默认为01011static dispatch_once_t onceToken;1213// dispatch_once宏可以保证块代码中的指令只被执⾏⼀次1415 dispatch_once(&onceToken, ^{1617// 在多线程环境下,永远只会被执⾏⼀次,instance只会被实例化⼀次1819 instance = [super allocWithZone:zone];2021 });22232425return instance;2627 }28293031 + (instancetype)sharedDemoObj3233 {3435// 如果有两个线程同时实例化,很有可能创建出两个实例来3637// if (!instance) {3839//// thread 1 0x0000A4041//// thread 2 0x0000B4243// instance = [[self alloc] init];4445// }4647//// 第⼀个线程返回的指针已经被修改!4849// return instance;5051return [[self alloc] init]; 5253 }54555657@end。
C++11实现线程安全的单例模式
C++11实现线程安全的单例模式1. 饿汉模式 使⽤饿汉模式实现单例是⼗分简单的,并且有效避免了线程安全问题,因为将该单例对象定义为static变量,程序启动即将其构造完成了。
代码实现:class Singleton {public: static Singleton* GetInstance() { return singleton_; }static void DestreyInstance() { if (singleton_ != NULL) { delete singleton_; }}private: // 防⽌外部构造。
Singleton() = default; // 防⽌拷贝和赋值。
Singleton& operator=(const Singleton&) = delete; Singleton(const Singleton& singleton2) = delete;private: static Singleton* singleton_;};Singleton* Singleton::singleton_ = new Singleton;int main() { Singleton* s1 = Singleton::GetInstance(); std::cout << s1 << std::endl; Singleton* s2 = Singleton::GetInstance(); std::cout << s2 << std::endl; Singleton.DestreyInstance(); return0;}2.懒汉模式 饿汉⽅式不论是否需要使⽤该对象都将其定义出来,可能浪费了内存,或者减慢了程序的启动速度。
所以使⽤懒汉模式进⾏优化,懒汉模式即延迟构造对象,在第⼀次使⽤该对象的时候才进⾏new该对象。
线程安全的单例模式
线程安全的单例模式一、懒汉式。
懒汉式是最简单的实现方式之一,它在第一次调用时才创建实例。
然而,这种实现方式在多线程环境下是不安全的,因为多个线程可能同时进入判断语句,导致创建多个实例。
为了解决这个问题,可以使用synchronized关键字来保证线程安全,但这会带来性能上的损失。
二、双重检查锁定。
双重检查锁定是一种在懒汉式的基础上改进的实现方式,它使用volatile关键字和synchronized代码块来确保线程安全。
在第一次检查时,如果实例已经被创建,就直接返回实例;否则,才进入同步代码块创建实例。
这种方式既保证了线程安全,又避免了每次都进入同步代码块带来的性能损失。
三、静态内部类。
静态内部类是一种利用Java类加载机制来保证线程安全的实现方式。
在这种方式中,外部类加载时并不会加载内部类,只有在第一次调用getInstance()方法时,才会加载并初始化内部类,从而保证了线程安全性。
这种方式不仅避免了同步带来的性能损失,而且实现起来也非常简洁。
四、枚举。
枚举是一种在Java中非常推荐的实现单例模式的方式。
枚举类型在Java中是线程安全的,并且只会装载一次,从而保证了单例的实现。
使用枚举实现单例模式不仅简洁,而且可以防止反射和序列化带来的问题。
总结。
在多线程环境下,实现线程安全的单例模式是非常重要的。
本文介绍了懒汉式、双重检查锁定、静态内部类和枚举这四种常见的实现方式。
在选择实现方式时,需要根据具体的需求来权衡各种方式的优缺点,以达到最佳的效果。
同时,也需要注意避免反射和序列化带来的问题,确保单例模式的安全性和稳定性。
希望本文能够帮助读者更好地理解和实现线程安全的单例模式。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
浅议单例模式之线程安全
作者:远航的兵时间:2013-01-30
[摘要]单例模式是一种常见的设计模式,在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。
正是由于这个特点,单例对象通常作为程序中的存放配置信息的载体,因为它能保证其他对象读到一致的信息。
这种方式只需访问该单例对象即可达到统一但是在多线程环境下,但是随着应用场景的不同,也可能带来一些同步问题。
本文将探讨一下在多线程环境下,使用单例对象时可能会带来的同步问题,并给出可选的解决办法。
[关键字] Java 设计模式单例线程同步双重检查锁
[概念]
单例模式分类:懒汉式单例、饿汉式单例两种。
单例模式特点:
1、单例类只能有一个实例
2、单例类必须自己自己创建自己的唯一实例
3、单例类必须给所有其他对象提供这一实例
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例
[问题描述]
面试的时候,大家也许会被问到这样一个问题:请您写出一个单例模式(Singleton Pattern),当然都感觉比较简单,代码如下:
/**
*演示单例模式之饥饿模式
*@author Administrator
*
*/
public class EagerSingleton
{
private static EagerSingleton instance=new EagerSingleton();
private EagerSingleton()
{
}
public static EagerSingleton getSingleInstance()
{
return instance;
}
}
这种写法就是所谓的饥饿模式,每个对象在没有使用之前就已经初始化了。
这就可能带来潜在的性能问题:如果这个对象很大呢?没有使用这个对象之前,就把它加载到了内存中去是一种巨大的浪费。
针对这种情况,我们可以对以上的代码进行改进,使用一种新的设计思想——延迟加载(Lazy-load Singleton)。
/**
*演示单例模式之懒汉模式
*@author Administrator
*
*/
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton()
{
}
public static LazySingleton getSingleInstance()
{
if (instance == null)
{
instance = new LazySingleton();
}
return instance;
}
}
这种写法就是所谓的懒汉模式。
它使用了延迟加载来保证对象在没有使用之前,是不会进行初始化的。
但是,通常这个时候面试官又会提问新的问题来刁难一下。
他会问:这种写法线程安全吗?回答必然是:不安全。
测试结果:
这是因为在多个线程可能同时运行到判断instance为null,于是同时进行了初始化。
所以,这是面临的问题是如何使得这个代码线程安全?很简单,在那个方法前面加一个Synchronized就OK了。
/**
*演示单例模式之线程安全
*@author Administrator
*
*/
public class ThreadSafeSingleton
{
private static ThreadSafeSingleton instance;
private ThreadSafeSingleton()
{
}
public static synchronized ThreadSafeSingleton getSingleInstance() {
if (instance == null)
{
instance = new ThreadSafeSingleton();
}
return instance;
}
}
写到这里,面试官可能仍然会狡猾的看了你一眼,继续刁难到:这个写法有没有什么性能问题呢?答案肯定是有的!同步的代价必然会一定程度的使程序的并发度降低。
那么有没有什么方法,一方面是线程安全的,有可以有很高的并发度呢?我们观察到,线程不安全的原因其实是在初始化对象的时候,所以,可以想办法把同步的粒度降低,只在初始化对象的时候进行同步。
[解决方案]
这里有必要提出一种新的设计思想——双重检查锁(Double-Checked Lock)。
/**
*演示单例模式之双重锁定
*@author Administrator
*
*/
public class DoubleCheckedSingleton {
private static DoubleCheckedSingleton instance;
private DoubleCheckedSingleton()
{
}
public static synchronized DoubleCheckedSingleton getSingleInstance() {
//性能改进——双重锁定: Double-Check Locking
if(instance==null) // 1. 先判断
{
synchronized (DoubleCheckedSingleton.class) // 2. 再同步
{
if (instance == null) //3. 再判断
{
instance = new DoubleCheckedSingleton(); //4. 实例化}
}
}
return instance;
}
}
这种写法使得只有在加载新的对象进行同步,在加载完了之后,其他线程就可以判断当前实例对象是否为空,如非空,并跳过锁的的代价直接返回当前单例对象了。
做到很好的并发度。
至此,上面的写法一方面实现了Lazy-Load,另一个方面也做到了并发度很好的线程安全,一切看上很完美。
这是,面试官可能会对你的回答满意的点点头。
但是,当你此时提出说,其实这种写法还是有问题的!面试官也许会对你刮目相看!!
问题在哪里?假设线程A执行到调用上述getSingleInstance()方法,它判断对象为空,于是线程A执行下面初始化这个对象,但初始化是需要耗费时间的,但是这个对象的地址其实已经存在了。
此时如果线程B也执行调用上述getSingleInstance()方法,它判断不为空,于是直接跳到最后,返回得到了这个对象。
但是,这个对象还没有被完整的初始化!得到一个没有彻底初始化完全的对象有什么用!!
关于这个Double-Checked Lock的讨论有很多,目前公认这是一个Anti-Pattern(即:反面
模式),不推荐使用!所以当这个面试官听到你的这番答复,他会不会被Hold不住呢?
那么有没有什么更好的写法呢?
有!这里又要提出一种新的模式——Initialization on Demand Holder.这种方法使用内部类来做到延迟加载对象,在初始化这个内部类的时候,JLS(Java Language Sepcification)会保
证这个类的线程安全。
这种写法最大的巧妙在于,完全使用了Java虚拟机的机制进行同步保证,没有一个同步的关键字。
/**
*演示单例模式之完美实现
*@author Administrator
*
*/
public class Singleton
{
private static class SingletonHolder
{
public final static Singleton instance = new Singleton(); }
public static Singleton getInstance()
{
return SingletonHolder.instance;
}
}
测试结果:
单个线程
多线程
至此,单例模式以及线程安全,我们做了一个系统的比较,希望对你有所帮助![参考链接]
Double-Checked Lock :
/wiki/Double-checked_locking
Initialzation on Demand Holder:
/wiki/Initialization_on_demand_holder_idiom
作者联系方式:
Email:navystar@。