首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

深度好文 | Java 重入锁内存可见性分析

就是通过重入锁的保护并行对共享变量进行自增。 突然想到一个问题:共享变量 count 没有加 volatile 修饰,那么在并发自增的过程当中是如何保持内存立即可见的呢?...几个概念 Java Memory Model (JMM) 即 Java 内存模型,直接引用 wiki 定义: "The Java memory model describes how threads in...Happens-before 对于 volatile 关键字大家都比较熟悉,该关键字确保了被修饰变量的内存可见性。...that thread 其中第 3 条就定义了 volatile 相关的 happens-before 原则,类比下面的同步机制,一图胜千言: 也就是说 volatile 写操作会把之前的共享变量更新一并发布出去...总结 针对本文开头提出的内存可见性问题,有着一系列的技术依赖关系才得以实现:count++ 可见性 → volatile 的 happens-before 原则 → volatile 底层 LOCK prefix

1.1K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Java 并发篇03 -序性、可见性、原子性。

    这篇文章,我们将给大家来讲解引起我们并发问题的三大因素--— 有序性、可见性、原子性。这三个问题是属于并发领域的所以并不涉及语言。 首先,我们来聊聊什么是安全性。...并发编程实战》 通过上面的引用,我们知道了: 单线程一定是线程安全的 无状态对象一定是线程安全的 上面讲到的无状态对象是指 方法的计算过程只存在于线程栈上的局部变量中,并且只能有当前正在执行的线程访问...就是我们下面讲到的可见性。...这就是缓存可见性的问题。 如果循环竞争的次数很小,比如 10次,那么结果可能还是对的,但是次数增大,那么结果差的就越大。...但是在我们的并发编程中,就出现了意想不到了。 首先大家要记住一点 不能通过 happens-before 原则推导的,JMM允许重排。

    49820

    java并发之原子性、可见性、有序性

    从上面可以看出,Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现更大范围操作的原子性,可以通过synchronized和Lock来实现。...可见性见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 于可见性Java提供了volatile关键字来保证可见性。...而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。...在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。...在Java里面,可以通过volatile关键字来保证一定的“有序性”(具体原理在下一节讲述)。

    1K20

    Java 并发编程(三):如何保证共享变量的可见性

    我们使用同步的目的不仅是,不希望某个线程在使用对象状态时,另外一个线程在修改状态,这样容易造成混乱;我们还希望某个线程修改了对象状态后,其他线程能够看到修改后的状态——这就涉及到了一个新的名词:内存(省略...)可见性。...要了解可见性,我们得先来了解一下 Java 内存模型。...Java 内存模型(Java Memory Model,简称 JMM)描述了 Java 程序中各种变量(线程之间的共享变量)的访问规则,以及在 JVM 中将变量存储到内存→从内存中读取变量的底层细节。...好了,共享变量的可见性就先介绍到这。希望本篇文章能够对大家有所帮助,谢谢大家的阅读。 精彩回顾: Java 并发编程(一):摩拳擦掌 Java 并发编程(二):线程安全性

    78530

    Java并发编程(一)---原子性,可见性,有序性

    摘要 并发编程世界里,由于CPU缓存导致的可见性问题,线程切换导致的原子性问题,以及编译器重排序导致的有序性问题是并发编程Bug的根源。...有序性 在并发时,由于编译器重排序导致不是按照程序的顺序执行。...可见性 一个线程对共享变量的修改。另外一个线程能够立刻看到,我们称之为可见性。...可见性问题可能在各个环节产生,比如:前面提到的指令重排序产生的可见性问题,另外在编译器的优化或者某些硬件的优化都会产生可见性问题。...总结 并发编程中主要的问题就是可见性问题, 原子性问题,有序性问题。本文介绍了这三种问题的发生原因,以及发生的场景。

    25510

    Java并发编程学习3-可见性和对象发布

    为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。...Java内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非 volatile 类型的 long 和 double 变量,JVM允许将64位的读操作或写操作分解为两个32位操作。...1.3 加锁与可见性内置锁可以用于确保某个线程以一种预测得方式来查看另一个线程的执行结果,如下图所示。...1.4 volatile 变量Java 语言提供了一种稍弱的同步机制,即 volatile 变量,用来确保将变量的更新操作通知到其他线程。...相比用锁来确保 asleep 更新操作的可见性,这里采用 volatile 变量,不仅满足了更新操作的可见性,而且代码逻辑也变得更加简单,更利于理解。

    21921

    简单了解下Java并发编程对象共享的可见性问题

    你好,这里是codetrend专栏“高并发编程基础”。可见性是一个复杂的属性,因为它经常违背我们的直觉。...可能的输出结果如下:Non-atomic count: 17809Atomic count: 20000加锁与可见性Java 中,加锁和可见性是两个关键概念,用于保证多线程环境下的线程安全和正确性。...Java 提供了一些机制来确保可见性:volatile 关键字:可以用于修饰共享变量,当一个线程修改了 volatile 变量的值后,会立即将新值刷新到主内存,并且其他线程在访问该变量时会从主内存中读取最新的值...可见性机制则确保当一个线程修改共享变量的值后,其他线程能够立即感知到这个变化。这两个概念都是保证多线程程序正确性的重要手段。volatile在Java中,volatile 是一种关键字,用于修饰变量。...对于复合操作,例如 num++,如果多个线程同时对 num 进行自增操作,虽然每个线程都会看到最新的值,但由于并发操作的执行顺序不确定,最终结果可能不符合预期。

    8810

    Java并发编程与高并发之线程安全性(原子性、可见性、有序性)

    10、对于可见性,JVM(java内存模型)提供了synchronized、volatile。可见性,JVM提供的synchronized。...11、可见性,volatile,通过加入内存屏障和禁止重排序优化来实现可见性的。...2)、可见性,是指一个线程对主内存的修改,可以及时的被其他线程观察到。在可见性里面,需要注意synchronized、volatile关键字。   ...为了屏蔽各种硬件和操作系统内存的访问差异,以实现Java程序在各种平台下都能达到一致的并发效果,Java虚拟机提供了Java内存模型(Java Memory Model,简称JMM)。...程序是多线程的,在你的java程序中,每个CPU上一个线程可能是并发执行的。

    87111

    并发编程之内存可见性问题

    内存可见性问题 关于内存可见性问题,简单一点说就是一个线程对内存中的一个共享变量进行修改操作,这个修改操作对其他线程是可见的,说通俗一点, 就是另外一个线程读取这个变量的值是读取修改后的值,也就是最新的值...那么引起内存可见性的原因是什么呢?...Java内存可见性Java内存模型中,规定每个线程有一个独立工作区域,叫做工作内存,当一个线程对某个共享变量进行修改操作的时候,先从主存中获取到这个共享变量, 然后保存在自己的工作内存中,对其进行修改后将修改后的值保存在工作内存中...,然后更新到主内存中,由于每个线程都有独立的工作内存,所以也是内存不可见的, 现在假如线程1修改了共享变量后,由于内存不可见性,那么其他的线程去主存里面就读取到的就可能是线程1修改之前的变量。...解决内存可见性我们可以通过加锁或者volatile关键字,他们能保证内存的可见性,但是注意,volatile只能保证内存可见性,并不能保证原子性,而加锁可以保证原子性,不过加锁的效率不高,后面我会再接着说锁和

    41120

    Java并发编程实战 02Java如何解决可见性和有序性问题

    摘要 在上一篇文章[Java并发编程实战 01并发Bug的源头](https://mp.weixin.qq.com/s/QT44HS47l_ir08pCZeFU5Q)当中,讲到了CPU缓存导致可见性、线程切换导致了原子性...那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经常考核到) 什么是Java内存模型?...现在知道了CPU缓存导致可见性、编译优化导致了有序性问题,那么最简单的方式就是直接禁用CPU缓存和编译优化。但是这样做我们的性能可就要爆炸了~。我们应该按需禁用。...管程是一种通用的同步原语,在Java中,synchronized是Java里对管程的实现。 管程中的锁在Java里是隐式实现的。...参考文章:极客时间:Java并发编程实战 02 个人博客网址: https://colablog.cn/ 如果我的文章帮助到您,可以关注我的微信公众号,第一时间分享文章给您

    35820

    探索JAVA并发 - 重入锁和不可重入锁

    什么是重入锁,什么是不可重入锁,它们是如何实现的?...定义 重入锁:当线程获取某个锁后,还可以继续获取它,可以递归调用,而不会发生死锁; 不可重入锁:与重入相反,获取锁后不能重复获取,否则会死锁(自己锁自己)。 不可重入锁 用代码说话。...重入锁 不可重入锁扩展一下,增加一个计数器,同一个线程每次获取锁计数器加1,释放锁减1,为0时释放锁。...基于自旋锁实现重入锁 直接用上个例子的代码改一下: import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock...ReentrantLock ReentrantLock是Java中很常见的工具类, 从名字就可以看出,它是个重入锁,用法也很简单: import java.util.concurrent.locks.ReentrantLock

    2.9K41

    并发编程系列之变量可见性问题探究

    并发编程系列之变量可见性问题探究 1、什么是并发中的变量可见性问题 以例子的形式看看,定义一个变量,先用static修饰,在主线程修改之后,看看在新开的子线程里能被看到?...然后怎么才能让并发线程看见?...解答这个问题,需要涉及到Java的内存模型,如下所示,Java内存模型及操作规范: 共享变量都是放在主内存中的 每个线程都有自己的工作内存,线程只可操作自己的工作内存 线程要操作共享变量,需要从主内存中读取到工作内存...只要求顺序执行,不一定是连续执行 图引用网上资料: 3、保证变量可见性的方法 final变量 synchronized volatile修饰 4、Synchronized怎么做到可见性 synchronized...volatile只能修饰成员变量 在多线程并发的场景才使用 volatile支持并发编程三大特效? 并发编程三大特效:原子性、有序性、可见性

    28160

    Java并发-显式锁篇【重入锁+读写锁】

    作者:汤圆 个人博客:javalover.cc 前言 在前面并发的开篇,我们介绍过内置锁synchronized; 这节我们再介绍下显式锁Lock 显式锁包括:重入锁ReentrantLock、读写锁...重入锁,实现了显式锁,意思就是重入的显式锁(内置锁也是重入的) 读写锁,将显式锁分为读写分离,即读读并行,多个线程同时读不会阻塞(读写,写写还是串行) 下面让我们开始吧 文章如果有问题,欢迎大家批评指正...,只有在内置锁满足不了需求时,再采用显式锁(比如定时、中断、公平性) 如果是读多写少的场景(比如配置数据),推荐用读写锁 总结 重入锁 ReentrantLock:需显式获取锁和释放锁,切记要在...因为现在内置锁的性能跟显式锁差别不大 而且显式锁因为需要手动释放锁(需在finally块中释放),所以会有忘记释放的风险 如果是读多写少的场合,则推荐用读写锁(成对的读锁和写锁需从同一个读写锁类获取) 参考内容: 《Java...并发编程实战》 《实战Java并发》 后记 最后,祝愿所有人都心想事成,阖家欢乐

    54010

    Java内存模型之可见性分析

    线程通信产生数据竞争 简要的源代码 // constant.java final int P = 10; final int C = 20; // shared.java int pwrite = 0;...public void run(){ cwrite = C; // --3 cread = pwrite;// 消费者线程需要生产者线程的pwrite数据 -4 } 在上述两个线程中分析 线程在并发下...JMM下的并发问题 其一,读取到的共享数据不一定是写操作之后的数据,也就是写操作对读操作不可见(缓存导致) 其二,JMM为了提升性能对代码进行重排序,那么就会导致数据产生的结果和预期的不一致(重排序导致...JMM可见性解决方案 线程之工作内存 JMM抽象之工作内存(线程本地内存) 线程栈中的存储的变量,如局部变量,方法参数,异常处理参数等 CPU高速缓存 线程,工作内存,JMM与主内存 ?...从上述可知,在JVM运行数据区中,工作内存与主内存是通过JMM模型规范来完成彼此之间的数据交互,因此可以通过JMM定义的内存语义规范来提供数据变量的可见性 基于缓存问题解决方案 JMM规范规定使用针对的技术手段时

    58640

    Java多线程--对象的可见性

    最近在看《Java并发编程实战》,并发方面的知识,今天看到了对象的可见性,在这里分享一下。   ...因为我们在执行某一线程的读操作的时候,其实并不知道是否有其他线程正在进行写操作,所以我们上面说到的可见性就在这里展开命题,我读操作的时候要知道另一个线程在写操作,这就是线程的安全性。...注意访问Volatile 并不会加锁,因此也就不会阻塞了,虽然性能上比Synchronized轻量级,但是牺牲了可见性,具体的不同我们在下一篇进行讲解。   ...加锁机制可以确保可见性和原子性。而Volatile 只确保可见性。   当满足下面情况才使用Volatile : 对变量的操作不依赖当前的值。就是比如i++ 该变量不会是不可变类型。

    78840
    领券