`
jaesonchen
  • 浏览: 299867 次
  • 来自: ...
社区版块
存档分类
最新评论

Java的可见性和原子性

 
阅读更多

1. 工作内存和主内存

  • 所有的变量都存在主内存中(一份)
  • 每个线程有自己独立的工作内存(主内存中该变量的一份拷贝)

2. 可见性和共享变量

  • 可见性:一个共享变量的值能够及时地被其他线程看到
  • 共享变量:如果一个变量在多个线程的工作内存中都存在拷贝,那么它就是这几个线程的共享变量

下图可以反映以上说明:

3. 约束

  • 线程对共享变量的操作只能在自己的工作内存中进行,不能直接修改主内存
  • 不同线程之间无法访问其他线程工作内存中的变量,必须通过主内存来访问其他线程工作内存中的变量

4. 共享变量可见性的原理

线程1对工作内存1的修改能及时让线程2及时可到,就是可见了。

4.1 可见性的步骤

  1. 将工作内存1中更新后的值写入主内存
  2. 主内存将最新的共享变量的值写入工作内存2

4.2 保证可见性的必要条件

  • 工作内存更新的共享变量值要及时写入主内存
  • 主内存及时更新共享变量的值写入工作内存2

synchronized实现可见性

5.1 synchronized实现的内容

  1. 原子性(同步)
  2. 可见性

5.2 JMM关于synchronized 的规定

  1. 解锁前必须把工作内存最新值写入主内存
  2. 加锁前清空工作内存的共享变量值,从主内存更新最新值

5.3 synchronized互斥代码的过程

  1. 获得互斥锁
  2. 清空工作内存
  3. 从主内存拷贝最新变量复制到自己的工作内存
  4. 执行代码
  5. 将更改的共享变量值写入主内存
  6. 释放互斥锁

6 volatile实现可见性

首先在说volatile实现可见性方法之前说一下编译重排序

6.1 重排序

编译器或处理器为了提高性能做优化,调整了执行顺序使得和书写顺序不同

6.2 as if serial语义

无论如何排序,程序执行结果与代码按照书写顺序执行的结果一致。在单线程情况下,遵循as if serial语义

volatile通过内存屏障和禁止重排序优化来实现可见性

  • 写操作后加入store屏障指令:写之后强行将更新的值写入主内存
  • 读操作前加入load屏障指令:读之前及时从主内存更新最新值

6.3 volatile无法实现原子性

  • 一般来说自增操作无法保证其原子性

解决方案:

  1. 同步块
  2. ReentrantLock(java.util.concurrent.locks) 3.AtomicInteger(java.util.concurrent.atomic)

多线程中安全使用volatile需要同时满足以下2点

  1. 对变量的写入操作不依赖当前值(比如自增、自减等操作;)
  2. 不能包含在一个不变式中(比如low<up,永远成立的)

7 synchronized和volatile的比较

  1. volatile不需要加锁,更加轻量级,不会阻塞线程
  2. 从内存可见性角度,volatile变量读等价于加锁,写等价于解锁
  3. synchronized可以同时保证原子性和可见性,而volatile一般来说只能保证可见性
  4. volatile需要注意使用的风险
  5. volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
  6. volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化 原文地址:http://blog.csdn.net/uniquewonderq/article/details/48477265
分享到:
评论

相关推荐

    java并发理论基础、可见性、原子性、有序性详解

    本资源涵盖了Java并发编程的理论基础和实践,主要包括可见性、原子性和有序性的详细介绍,以及多线程的使用原因、好处和坏处等方面的内容。 Java并发编程是一种高效的编程技术,通过多线程实现将计算过程中不必要的...

    14、深入理解并发可见性、有序性、原子性与JMM内存模型

    深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发...

    Java内存模型--原子性;有序性;可见性1

    原子性有序性可见性

    java 并发操作之原子性与可视性1

    可见性可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。这个变量a具有可见性,但是a++ 依然是一个非原子操作,也就这这个操作同样存在线程安

    Java多线程中提到的原子性和可见性、有序性1

    如果应场景需要个更范围的原性保证,Java内存模型还提供了lock和unlock操作来满这种需求,尽管虚拟机未把lock与unlock操作直接开放给户使,但是却

    并发二:原子性、可见性、有序性.pdf

    并发二:原子性、可见性、有序性

    14、深入理解并发可见性、有序性、原子性与JMM内存模型(1).pdf

    14、深入理解井发可见性、有序性、原子性与JMM内存模型 (1).pdf 15、CPU缓存架构详解&高性能内存队列Disruptor 实战 (1).pdf 16、常用并发设计模式精讲 (1).pdf designpattern.zip disruptor.zip forkjoin.zip jmm(1...

    java 并发中的原子性与可视性实例详解

    主要介绍了java 并发中的原子性与可视性实例详解的相关资料,原子性是说一个操作是否可分割。可见性是说操作结果其他线程是否可见。需要的朋友可以参考下

    Java并行(3):可见性重访之锁、Volatile与原子变量1

    1. 过期数据 2. 锁的可见性 4. 原变量 1. JSL 第三版 2. Java Concurrency in Practice

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

    那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经常考核到) 什么是Java内存模型? 现在知道了CPU缓存导致可见性、编译优化导致了有序性问题,那么最简单的方式...

    Java并发:volatile内存可见性和指令重排

     1、保证内存可见性  2、防止指令重排  此外需注意volatile并不保证操作的原子性。  (一)内存可见性  1 概念  JVM内存模型:主内存和线程独立的工作内存  Java内存模型规定,对于多个线程共享的变量...

    java多线程安全性基础介绍.pptx

    锁不仅保证原子性还保证可见性 有序性 多个线程操作共享对象导致的状态不一致问题 原因 共享资源的竞态条件问题 问题 竞态条件 指令重排序 工作内存中主内存同步延迟 解决 要有安全策略文档或注释 不共享...

    Java并发编程实战 03互斥锁 解决原子性问题

    在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和有序性的问题,那么还有一个原子性问题咱们还没解决。在第一篇文章01并发编程的Bug源头当中,讲到了把一个或者多个操作在 CPU 执行的过程中不...

    Test2.java

    java多线程的通讯共享数据就是共享内存,共享内存主要有可见性和有序原子性。java 内存原型JMM解决可见有序,线程锁synchronized所解决它的原子性。 JMM内存原型:java可以在不同操作系统不同硬件存储逻辑下运行的...

    java面试题-java-interview-questions-master.zip

    java面试题_java-interview-questions-...2、 缓存导致的可见性问题 解决办法:synchronized、volatile、LOCK,可以解决可见性问题 3、 编译优化带来的有序性问题 解决办法:Happens-Before 规则可以解决有序性问题

    解开Volatile的面纱V1.1

    解决并发问题,我们一般需要从原子性、可见性和有序性三方面入手,借助Java关键字及各种同 步工具类来实现。 原子性、可见性、有序性三特性: 1. 原子性:原子性就是说一个操作不能被打断,要么执行完要么不执行。 2...

    Java并发编程实战

    3.1.3 加锁与可见性 3.1.4 Volatile变量 3.2 发布与逸出 3.3 线程封闭 3.3.1 Ad-hoc线程封闭 3.3.2 栈封闭 3.3.3 ThreadLocal类 3.4 不变性 3.4.1 Final域 3.4.2 示例:使用Volatile类型来发布不可变对象...

    Java并发编程.docx

    o可见性 :一个线程对共享变量的修改,另一个线程能立刻看到。 缓存 可导致可见性问题。 o原子性 :一个或多个CPU执行操作不被中断。 线程切换 可导致原子性问题。 o有序性 :编译器优化可能导致指令顺序发生...

    java内存屏障与JVM并发详解实用.pdf

    内存屏障的重要性在于,它可以解决多线程程序中的一些问题,如可见性、原子性和顺序性问题。当多个线程访问共享资源时,内存屏障可以确保这些线程按照正确的顺序执行操作,从而避免了数据不一致和线程安全问题。 三...

    上海某大厂java面试真题与解析

    1、"上海某大厂面试真题,掌握并发编程三大核心—原子性、可见性和有序性,是优化高并发系统性能的关键所在。#Java并发编程 #电商技术挑战" 2、“了解多线程创建的四种方式,包括Runnable、Callable以及线程池的...

Global site tag (gtag.js) - Google Analytics