public class CachePool{
private volatile static CachePool sharedPool;
private CachePool(){}
public static CachePool getSharedPool(){
if(sharedPool==null)
{
synchronized(CachePool.class){
if(sharedPool==null){
sharedPool=new CachePool();
}
}
}
return sharedPool;
}
//其他方法
}
以上是存取CachePool对象的一段代码。
这里用到了volatile和两个if block来存取唯一化的CachePool的对象。
为什么既然这里用到了volatile,为什么要用到两个if block呢?
为什么不把synchronized来定义getSharedPool()方法呢?
假设我们synchronized整个getSharedPool(),那么我们每次用CachePool.getSharedPool()去取得sharedPool对象的时候,都要执行同步,这样会对性能造成影响。因此我们把syncronized抽开,放到第一个if block里面去执行,这样就保证了,当sharedPool对象取得之后,就不用再去执行这个同步化的if block。
我们假设两个线程t1和t2,分别开始在栈1和栈2执行getSharedPool()方法,t1判断到sharedPool是null, t2也判断是null, 因此t1, t2同时进入第一个if block, 假设t1比t2稍快执行同步部分,t1就率先实例化了CachePool这个类,把实例化的sharedPool返回,并把钥匙交给t2,t2要进入这个t2内存空间的cachePool还是null吗?如果sharedPool对象没有声明volatile,t2内存里读取的值就还是null,那么就还要new一次!不过这里sharedPool被volatile了,t2和t2对这个值是共享内存,因此t2读到的不再是null,因此,不再执行第二个if block,直接返回第一个new出来的对象的引用。
之后的线程调用getSharedPool(),第一个if block之后就直接return t1实例化出来的引用了,不再执行同步化的部分。
volatie和两个if block,加上一个syncronized,保证了sharedPool的对象唯一。
分享到:
相关推荐
【volatile源码分析1】 Java中的volatile关键字是一个关键的同步机制,它在多线程编程中扮演着重要的角色。在面试和技术讨论中,volatile经常成为焦点,但其工作原理却常常引发争议。本文将从JVM、C++以及汇编语言...
在C++编程语言中,`const`和`volatile`是两个非常重要的关键字,它们用于修饰变量,赋予变量特殊的属性。这两个关键字在理解程序的行为、内存模型以及多线程编程中起到至关重要的作用。在此,我们将深入探讨`const`...
理解和正确使用`volatile`和`const`关键字对于编写高质量的C语言代码至关重要,尤其是在嵌入式系统开发中。通过确保编译器正确处理这些变量,可以避免许多难以调试的错误,提高系统的稳定性和可靠性。
2. **单例模式中的双重检查锁定**:在实现线程安全的单例模式时,`volatile`关键字可以用来保证实例创建过程中的可见性和有序性,避免多线程环境下可能出现的问题。 3. **懒汉式初始化**:在某些情况下,为了避免...
《深入理解Volatile》 ...正确理解和使用volatile可以避免不必要的数据冲突,提高程序的正确性和可靠性。但在使用时,需要注意其局限性,特别是在多线程环境下,volatile并不能完全替代同步机制。
本文将深入分析在硬件层面上Inter处理器是如何实现Volatile的,通过深入分析能帮助我们正确的使用Volatile变量。
`volatile`关键字在C语言中是一个非常重要的概念,主要用于处理多线程环境或者与硬件交互时的内存可见性问题。它的主要作用是确保对变量的修改能够立即...理解和正确使用`volatile`对于编写健壮的并发代码至关重要。
本篇将深入解析单例设计模式的四种实现方式,并通过具体的案例进行详细分析。 一、懒汉式(线程不安全) 懒汉式单例的特点是在类被加载时并不创建实例,而是首次调用getInstance()方法时才创建。这种实现方式简单...
"volatile的用法讲解" volatile是一种特殊的变量修饰符,它告诉编译器,这个变量的值可能会被意外地改变,因此编译器不能对其进行优化,以确保每次读取该变量时都能获取最新的值。下面是volatile变量的使用场景: ...
Volatile是C语言中的一个类型修饰符,用于告诉编译器该变量可能会在程序的控制之外被改变,从而禁止编译器对涉及该变量的代码做优化处理。这种用法在多线程、中断服务程序和硬件访问等场合特别重要。接下来详细说明...
在嵌入式系统编程中,`volatile`关键字的正确使用对于确保程序的稳定性和可靠性至关重要。它主要用于标记那些可能在程序运行过程中被外部因素(如硬件中断、多线程环境等)修改的变量。不当使用`volatile`不仅可能...
只有当我们使用 volatile 关键字时,编译器才会按照我们编写的代码来生成汇编代码。 在第三个例子中,我们可以看到,使用 volatile 关键字可以避免编译器的优化,并且可以确保变量的值是正确的。在这个例子中,我们...
在iOS和Mac开发中,Objective-C是主要的编程语言,它在定义实例变量或属性时提供了几个关键的修饰符,包括`volatile`、`nonatomic`和`atomic`。这些关键字对于理解多线程环境下的数据同步和内存管理至关重要。本文将...
然而,如果`ptr`指向一个`volatile`类型的变量,那么编译器可能会生成以下代码: ```c int square(volatile int *ptr) { int a, b; a = *ptr; b = *ptr; return a * b; } ``` 如果`ptr`指向的值在两次...
本篇文章将深入分析Volatile的实现原理,结合`LinkedTransferQueue`和`TransferQueue`这两个与并发相关的Java源码,探讨其在多线程环境中的应用。 首先,我们需要理解Java内存模型(JMM,Java Memory Model),它是...
单例模式和工厂模式是两种常见的软件设计模式,在面向对象编程中扮演着重要的角色。它们都是为了解决特定的问题而提出的解决方案,但有着不同的应用场景和设计思路。 **单例模式** 是一种限制类实例化次数的模式,...
在 `release` 模式下,如果没有使用 `volatile`,第二次读取 `i` 的值时可能不会从内存中重新读取,而是使用之前缓存的值。但使用了 `volatile` 后,每次访问 `i` 都会从内存中重新读取,确保获取的是最新值。 ####...