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

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

就是通过可重入锁的保护并行对共享变量进行自增。 突然想到一个问题:共享变量 count 没有加 volatile 修饰,那么在并发自增的过程当中是如何保持内存立即可见的呢?...上面的代码做自增肯定是没问题的,可见 LOCK 不仅仅保证了独占性,必定还有一种机制保证了内存可见性。 可能很多人和我一样,对 LOCK 的认知是如此 “理所应当”,以至于从没有去思考为什么。...几个概念 Java Memory Model (JMM) 即 Java 内存模型,直接引用 wiki 定义: "The Java memory model describes how threads in...Happens-before 对于 volatile 关键字大家都比较熟悉,该关键字确保了被修饰变量的内存可见性。...总结 针对本文开头提出的内存可见性问题,有着一系列的技术依赖关系才得以实现:count++ 可见性 → volatile 的 happens-before 原则 → volatile 底层 LOCK prefix

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

    简单的鼠标可拖动DIV 兼容IEFF

    一个简单的可拖动div,随着鼠标的移动,div可随之走动 主要思路: 一个div,注册监听onmousedown事件,然后处理获取的对象及其相关值(对象高度,clientX/clientY位置等) 并继而转为监测...onmousemove事件,在鼠标移动事件中更新div对象的位置属性 鼠标松开的时候解除监听,更新位置完成。...需要注意的两点: 1.更新对象的位置需要用到o.style.left等,这些CSS属性只能内嵌才能被访问到: div id="box" style="left:200px;top:200px;"> box...div> 放在中是无法访问的,比如: #box{position: absolute;left:200px;top:200px;width: 200px;} 假如这样做...o.releaseCapture() : window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP) 最后是一个可随鼠标拖动的div ?

    2.6K10

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

    最近在看《Java并发编程实战》,并发方面的知识,今天看到了对象的可见性,在这里分享一下。   ...因为我们在执行某一线程的读操作的时候,其实并不知道是否有其他线程正在进行写操作,所以我们上面说到的可见性就在这里展开命题,我读操作的时候要知道另一个线程在写操作,这就是线程的安全性。...我们了解到了重排序的概念,因此我们看到的结果其实和输出的结果是完全相反的,因为我们的想的是输出0,然后给number赋值42.   在没有同步介入的情况下,我们完全无法得到我们想要的值。   ...注意访问Volatile 并不会加锁,因此也就不会阻塞了,虽然性能上比Synchronized轻量级,但是牺牲了可见性,具体的不同我们在下一篇进行讲解。   ...而且Volatile 并不足以保证比如 i++这类递增操作的安全性,而是常用来表示某个操作完成或者是结束的状态标识符。   加锁机制可以确保可见性和原子性。而Volatile 只确保可见性。

    80740

    Java多线程中的内存可见性

    刚刚看了一下synchronized和volatile的区别,这里做一下笔记。 多线程中内存是如何分配的? 分为主内存和线程内存,当线程与其他线程共享一个变量时,便会把主内存的变量复制到线程内存中去。...Synchronized实现可见性 JMM对Synchronized规定: 线程加锁时,将清空线程内存中共享变量的值,从而使用共享变量时从主内存中重新读取新值。...java编译器保证as-if-serial,但是在多线程程序中并不能保证顺序执行。...Volatile实现可见性 加入内存屏障和禁止重排序优化来实现,会在volatile写操作后加入store屏障指令,读操作前加入load屏障指令。...Volatile不能保证变量操作的原子性 Lock实现可见性 Lock lock = new ReentrantLock(); lock.lock(); try{ }finally{

    49810

    关于Java变量的可见性问题

    摘要:关于java变量在工作内存和主存中的可见性问题 正文: package com.test;import java.util.concurrent.TimeUnit; public class...涉及知识解释 volatile:此关键字保证了变量在线程的可见性,所有线程访问由volatile修饰的变量,都必须从主存中读取后操作,并在工作内存修改后立即写回主存,保证了其他线程的可见性,同样效果的关键字还有...在CPU资源一直被占用的时候,工作内存与主内存中间的同步,也就是变量的可见性就会不那么及时!后面会验证结论。 Q2:为什么取消注释中的任何一个代码块(1,2,3),程序才会终止?...,以及sleep方法也会刷新主存的变量值到线程栈呢?,事实上我们前面说了synchronized只会保证在同步块中的变量的可见性,而is变量并不在该同步块中,所以显然不是这个导致的。...在上面的 A1 中我们已经说了即便有JVM的优化,但当CPU一直被占用的时候,数据的可见性得不到很好的保证,就像上面的程序一直循环做i++;运算占用CPU,而为什么加上上面的代码后程序就会停止呢?

    1K50

    Java并发编程之验证volatile的可见性

    Java并发编程之验证volatile的可见性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性。1:保证可见性 2:不保证原子性 3:保证顺序。那么怎么来验证可见性呢?...本文凯哥将通过代码演示来证明volatile的可见性。...我们来看看输出的结果: 编辑 可以看到控制台输出的结果,线程A更新完变量的值之后在自己内部获取到变量的值是更新后的,但是在主线程的工作缓存去获取后,依然是0.因为主线程依然还在运行着(红色按钮一直红色的...这次操作和上次操作唯一区别就是变量number添加了volatile关键字来修饰,但是主线程竟然能够获取到线程A修改后的数据,从而证明了volatile能够保证共享变量在其他线程的可见性。...Volatile第二个特性:不保证原子性的证明,欢迎继续学习凯哥【凯哥Java:kaigejava】下一篇文章《Java并发编程之验证volatile不能保证原子性》。

    68000

    Java多线程的可见性与有序性

    多线程的可见性 一个线程对共享变量值的修改,能够及时的被其他线程看到。 共享变量 如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。...Java内存模型 JMM(Java Memory Model,简称JMM)描述了Java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取出变量这样的底层细节。...不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量的传递需要通过主内存来完成 共享变量可见性实现的原理 线程1对共享变量的修改要想被线程2及时看到,必须经过如下2个步骤: 把工作内存1中更新过的共享变量刷新到主内存中...将主内存中最新的共享变量的值更新到工作内存2中 Java的内存模型: ?...Java语言层面支持的可见性实现方式有以下两种: synchronized volatile synchronized JMM关于synchronized的规定: 线程解锁前,必须把共享变量的最新值刷新到主内存中

    58920

    JAVA的原子性、可见性与有序性?

    JAVA的原子性、可见性与有序性了解一波。 原子性(Atomicity):一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。...可见性(Visibility):可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。...Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方式来实现可见性的,无论是普通变量还是volatile变量都是如此, 普通变量与volatile...因此,可以说volatile保证了多线程操作时变量的可见性,而普通变量则不能保证这一点。 除了volatile之外,Java还有两个关键字能实现可见性,即synchronized和final。...同步块的可见性是由“对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store、write操作)”这条规则获得的, 而final关键字的可见性是指:被final修饰的字段在构造器中一旦初始化完成

    1.5K10

    Java内存模型以及线程安全的可见性问题

    要了解Java内存模型,首先要了解什么是内存模型,之间在CPU缓存和内存屏障 中我们了解到缓存一致性问题以及处理器优化的指令重排序问题。为了保证并发编程中可以满足原子性、可见性及有序性。...目的是保证并发编程场景中的原子性、可见性和有序性。...可见性问题 可见性:主要是指一个线程对共享变量的写入可以被后续另一个线程读取到,也就说一个线程对共享变量的操作对另一个线程是可见的。...而可见性问题就是指一个线程对共享变量进行了写入而其他的线程却无法读取到该线程写入的结果,根据以下工作内存的缓存的模型我们可以知道,造成可见性的问题主要有两方面,一个是数据在写入的时候只是写入了缓存而没有写入主内存...可见性问题的解决方法 — volatile关键字 volatile关键字可以保证一个线程对共享变量的修改,能够及时的被其他线程看到。

    89930

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

    我们使用同步的目的不仅是,不希望某个线程在使用对象状态时,另外一个线程在修改状态,这样容易造成混乱;我们还希望某个线程修改了对象状态后,其他线程能够看到修改后的状态——这就涉及到了一个新的名词:内存(可省略...要了解可见性,我们得先来了解一下 Java 内存模型。...Java 内存模型(Java Memory Model,简称 JMM)描述了 Java 程序中各种变量(线程之间的共享变量)的访问规则,以及在 JVM 中将变量存储到内存→从内存中读取变量的底层细节。...换句话说,就是:普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主内存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。...精彩回顾: Java 并发编程(一):摩拳擦掌 Java 并发编程(二):线程安全性

    79130

    高级java必须清楚的概念:原子性、可见性、有序性

    原子性、可见性、有序性是多线程编程中最重要的几个知识点,由于多线程情况复杂,如何让每个线程能看到正确的结果,这是非常重要的。...在多线程情况下,每个线程的执行结果不受其他线程的干扰,比如说多个线程同时对同一个共享成员变量n++100次,如果n初始值为0,n最后的值应该是100,所以说它们是互不干扰的,这就是传说的中的原子性。...但n++并不是原子性的操作,要使用AtomicInteger保证原子性。 可见性 可见性是指某个线程修改了某一个共享变量的值,而其他线程是否可以看见该共享变量修改后的值。...像CPU的缓存优化、硬件优化、指令重排及对JVM编译器的优化,都会出现可见性的问题。 有序性 我们都知道程序是按代码顺序执行的,对于单线程来说确实是如此,但在多线程情况下就不是如此了。...明天我再讲讲volatile关键字,它能保证可见性、有序性,但不能保证原子性。

    637101

    Java中的可重入锁

    所谓重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。 synchronized 和 ReentrantLock 都是可重入锁。...可重入锁的意义在于防止死锁。 可重入锁简单演示 什么是 “可重入”,可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。...,可重入,就是可以重复获取相同的锁,synchronized和ReentrantLock都是可重入的 //可重入降低了编程复杂性 public class WhatReentrant { public...A类对象的锁,而其他线程是不可以的,这就是可重入锁。...可重入锁的概念和设计思想大体如此,Java中的可重入锁ReentrantLock设计思路也是这样。 synchronized和ReentrantLock 都是可重入锁。

    1.3K40

    记一次对Java多线程内存可见性的测试

    因为无法获知线程2对共享变量running做出的修改, 然后线程1一直处在运行状态。   这里简单说明一下Java Mememory Model简称JMM: ?   ...为了让例子最终能输出 Thread 1 finished   方法:很简单, 直接设置变量running为volatile,以保证其在多线程环境中的内存可见性问题。   ...本文的重点是对插入的内存屏障进行测试,所以以上只是开头。  测试volatile插入的内存屏障指令,变更代码为:   添加一个类,包含一个volatile的变量并赋值。   ...测试synchronized关键字对可见性的影响:   为了套用Happen-Before规则,这里直接在get()和doSetTrue()方法上加synchronized 也能保证可见性问题。...JMM关于synchronized的两条规定:   线程解锁前,必须把共享变量的最新值刷新到主内存中   线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值

    54710

    Java学习内存模型以及线程安全的可见性问题(八)

    (一)容易误解的部分 老铁很容易把JAVA的内存区域、JAVA的内存模型,GC分代回收的老年代和新生代也容易搞混,绕进去绕不出来。...学习多线程之前一定要搞明白这些问题,可能在你的内心一直认为多线程就是一个工具,所有的底层都是C++来写的,没办法去看,为什么要有java,java其实就是屏蔽了底层的复杂性。...① GC内存区域 堆的概念,老年代,新生代,Eden,S0,S1 ② JAVA的内存区域 JVM运行时的区域:java编译生成class,线程共享部分(方法区,堆内存),线程独占部分(虚拟机栈,本地方法栈...,程序计数器) ③ JAVA的内存模型(概念) 针对多核多CPU,多线程而制定的一套规范规则,不是一种开发技术。...② 原则 同一个线程里面对数据做了变动,后面的动作可以及时的看到,其实还是可见性。 某个monitor上的unlock动作 happens-before 同一个monitor上后续的lock动作。

    45810

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

    位操作在 Java 多线程编程中,对于一些操作,特别是涉及到 64 位数据类型的操作,可能会出现非原子操作的情况。...可能的输出结果如下:Non-atomic count: 17809Atomic count: 20000加锁与可见性在 Java 中,加锁和可见性是两个关键概念,用于保证多线程环境下的线程安全和正确性。...Java 提供了一些机制来确保可见性:volatile 关键字:可以用于修饰共享变量,当一个线程修改了 volatile 变量的值后,会立即将新值刷新到主内存,并且其他线程在访问该变量时会从主内存中读取最新的值...可见性机制则确保当一个线程修改共享变量的值后,其他线程能够立即感知到这个变化。这两个概念都是保证多线程程序正确性的重要手段。volatile在Java中,volatile 是一种关键字,用于修饰变量。...使用 volatile 关键字修饰的变量具有以下特性:可见性:volatile 保证了可见性,即当一个线程修改了 volatile 变量的值时,其他线程能够立即看到最新的值。

    9610

    深入设计模式:编写可维护、可扩展的Java代码

    引言在Java编程中,理解和应用设计模式是编写高质量、可维护、可扩展代码的关键。设计模式提供了一套在特定场景下解决常见问题的经验法则,通过合理运用设计模式,我们能够更好地组织和设计代码结构。...具体产品和具体工厂分别实现这两个抽象接口,通过工厂来创建具体产品的实例。这种方式能够实现对产品和工厂的解耦。3....观察者模式观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,所有依赖于它的观察者都会得到通知并更新。...import java.util.ArrayList;import java.util.List;// 主题接口interface Subject { void addObserver(Observer...结尾通过学习单例模式、工厂模式和观察者模式等设计模式,我们能够更好地组织和设计Java代码,使其更加灵活、可维护和可扩展。这些模式提供了一套通用的解决方案,能够在特定的场景下提高代码的质量。

    11410

    编写一个可复用的SpringBoot应用运维脚本

    本文尝试基于经验,总结之前生产使用的Shell脚本,编写一个可以复用的SpringBoot应用运维脚本,从而极大减轻SpringBoot应用启动、状态、重启等管理的工作量。...例如: nohup Command >/dev/null 2>&1 & 编写SpringBoot应用运维脚本 SpringBoot应用本质就是一个Java应用,但是会有可能添加特定的SpringBoot...允许的参数,下面会一步一步分析怎么编写一个可复用的运维脚本。...全局变量 考虑到尽可能复用变量和提高脚本的简洁性,这里先提取可复用的全局变量。...小结 SpringBoot是目前或者将来一段很长时间Web服务中的主流框架,笔者花了一点时间学习Shell相关的语法,结合nohup、ps等Linux命令编写了一个可复用的应用运维脚本,目前已经应用在测试和生产环境中

    58110
    领券