首页
学习
活动
专区
工具
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

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

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

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

99220

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

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

47720

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

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

74230

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

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

23010

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

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

76611

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

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

35920

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/ 如果我的文章帮助到您,可以关注我的微信公众号,第一时间分享文章给您

33420

探索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.7K41

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

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

24860

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

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

49910

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

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

75640

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规范规定使用针对的技术手段时

51540

Java 并发编程·Java 并发

Java 并发 线程状态转换 新建(New) 创建后尚未启动。 可运行(Runnable) 可能正在运行,也可能正在等待 CPU 时间片。...時雨:在 《Java 并发核心知识体系精讲》中,参考 Oracle 官方文档,标注实现多线程方式只有两种:实现 Runnable 接口和继承 Thread 类。...可见性见性指当一个线程修改了共享变量的值,其它线程能够立即得知这个修改。Java 内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值来实现可见性的。...在 Java 内存模型中,允许编译器和处理器对指令进行重排序,重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。...重入代码有一些共同的特征,例如不依赖存储在堆上的数据和公用的系统资源、用到的状态量都由参数中传入、不调用非重入的方法等。

2.6K31

Java内存模型(可见性有序性)

摘要 本文的主题是Java内存模型的可见性,主要解决以下几个问题: 什么是可见性 什么是有序性 指令重排序 如何保证线程间有序性 先行发生原则 volatile关键字 synchronized关键字...概念 1.1 什么可见性见性是指当一个线程修改了共享变量的值以后,其他线程可以立即得知这个修改。...这两个关键字我们放在后面单独讲(毕竟可见性、有序性都和他们有关)。 除了上述两个关键字,Java语言中有一个先行发生原则,这个原则是判断数据是否存在竞争,线程是否安全的主要依据。...volatile关键字之所以能保证可见性、有序性,是因为Java内存模型对volatile修饰的变量使用有着以下规则: 对volatile变量的use操作前必须要有load操作,对volatile变量的...本期的Java内存模型可见性-有序性介绍到这,我是shysh95,顺手关注+在看,我们下期再见!!!

39620
领券