1. 工作内存和主内存
- 所有的变量都存在主内存中(一份)
- 每个线程有自己独立的工作内存(主内存中该变量的一份拷贝)
2. 可见性和共享变量
- 可见性:一个共享变量的值能够及时地被其他线程看到
- 共享变量:如果一个变量在多个线程的工作内存中都存在拷贝,那么它就是这几个线程的共享变量
下图可以反映以上说明:
3. 约束
- 线程对共享变量的操作只能在自己的工作内存中进行,不能直接修改主内存
- 不同线程之间无法访问其他线程工作内存中的变量,必须通过主内存来访问其他线程工作内存中的变量
4. 共享变量可见性的原理
线程1对工作内存1的修改能及时让线程2及时可到,就是可见了。
4.1 可见性的步骤
- 将工作内存1中更新后的值写入主内存
- 主内存将最新的共享变量的值写入工作内存2
4.2 保证可见性的必要条件
- 工作内存更新的共享变量值要及时写入主内存
- 主内存及时更新共享变量的值写入工作内存2
synchronized实现可见性
5.1 synchronized实现的内容
- 原子性(同步)
- 可见性
5.2 JMM关于synchronized 的规定
- 解锁前必须把工作内存最新值写入主内存
- 加锁前清空工作内存的共享变量值,从主内存更新最新值
5.3 synchronized互斥代码的过程
- 获得互斥锁
- 清空工作内存
- 从主内存拷贝最新变量复制到自己的工作内存
- 执行代码
- 将更改的共享变量值写入主内存
- 释放互斥锁
6 volatile实现可见性
首先在说volatile实现可见性方法之前说一下编译重排序
6.1 重排序
编译器或处理器为了提高性能做优化,调整了执行顺序使得和书写顺序不同
6.2 as if serial语义
无论如何排序,程序执行结果与代码按照书写顺序执行的结果一致。在单线程情况下,遵循as if serial语义
volatile通过内存屏障和禁止重排序优化来实现可见性
- 写操作后加入store屏障指令:写之后强行将更新的值写入主内存
- 读操作前加入load屏障指令:读之前及时从主内存更新最新值
6.3 volatile无法实现原子性
- 一般来说自增操作无法保证其原子性
解决方案:
- 同步块
- ReentrantLock(java.util.concurrent.locks) 3.AtomicInteger(java.util.concurrent.atomic)
多线程中安全使用volatile需要同时满足以下2点
- 对变量的写入操作不依赖当前值(比如自增、自减等操作;)
- 不能包含在一个不变式中(比如low<up,永远成立的)
7 synchronized和volatile的比较
- volatile不需要加锁,更加轻量级,不会阻塞线程
- 从内存可见性角度,volatile变量读等价于加锁,写等价于解锁
- synchronized可以同时保证原子性和可见性,而volatile一般来说只能保证可见性
- volatile需要注意使用的风险
- volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
- volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化 原文地址:http://blog.csdn.net/uniquewonderq/article/details/48477265
相关推荐
Java并发编程是提升系统效率的关键技术...总之,理解Java并发编程中的可见性、原子性和有序性是编写高效、安全并发程序的关键。开发者需要掌握如何利用并发提升性能,同时处理好潜在的问题,确保程序的正确性和稳定性。
深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发...
Java多线程编程中,原子性、可见性和有序性是三个关键的概念,它们确保了多线程环境下的正确性。 1. 原子性(Atomicity) 原子性指的是一个操作不可被中断,要么全部执行,要么完全不执行。在Java中,非原生类型的...
总结来说,Java内存模型通过原子性、有序性和可见性保证了多线程环境下的数据一致性。理解并熟练运用这些概念是编写高效、线程安全的Java代码的基础。在实际开发中,应根据需求选择合适的方式来确保这三个特性,以...
在Java并发编程中,原子性和可见性是两个关键的概念,它们直接影响着多线程环境下的程序行为和数据一致性。理解这两个概念对于编写高效且线程安全的代码至关重要。 首先,让我们详细探讨一下原子性。原子性指的是一...
本文主要讲解了Java内存模型(JMM)中关于并发编程的三个基本概念:原子性、可见性和有序性。 原子性 原子性是指一个操作不会被线程调度机制打断,一旦开始,就一直运行到结束,中间不会有任何线程切换(context ...
下面是一个简单的实例,用于演示原子性和可见性的概念: ```java public class Test { volatile int a = 1; volatile boolean ready; public class PrintA extends Thread{ @Override public void run() { ...
根据提供的文档信息,本文将详细解析并发编程中的关键概念——原子性、可见性及有序性,并结合Java内存模型(JMM)来深入理解这些概念。同时,我们也会通过具体示例来探讨这些问题在实际编程中的应用。 ### 一、并发...
在Java并发编程中,内存可见性和线程安全是核心议题。本文将探讨三个关键概念:过期数据、锁的可见性以及Volatile关键字的作用。首先,我们来看一下“过期数据”这一问题。 1. 过期数据 在并发环境中,当多个线程...
Java中的Volatile关键字详解是Java中的一种关键字,用于保证线程之间的可见性、原子性和有序性。下面是对Java中的Volatile关键字详解的知识点总结: 一、基本概念 1. 可见性:可见性是一种复杂的属性,因为可见性...
在Java并发编程中,volatile关键字扮演着非常重要的角色,它可以确保变量的可见性和原子性。在多线程环境下,volatile关键字可以确保变量的修改对其他线程是可见的。本文将通过示例代码详细介绍Java并发volatile可见...
`AtomicLongArray`是Java并发库提供的一个原子性操作长整型数组的类,它支持线程安全的增加、减少、比较并设置、获取和设置等操作,而无需使用锁或其他同步机制。这使得在高并发场景下,多个线程可以并发地修改数组...
它通过 Unsafe 类提供的硬件级别的原子操作和 volatile 关键字保证了操作的原子性和可见性。在实际开发中,我们应该根据具体的应用场景选择合适的同步机制。对于简单的原子操作,AtomicInteger 是一个很好的选择。而...
这些机制可以帮助我们实现原子性和可见性。 Java内存模型原子性原理是指在多线程环境下,共享变量的访问需要满足原子性要求。我们可以使用同步机制来实现原子性,例如使用synchronized关键字和Lock接口等。通过这些...
并发编程的三大特性包括原子性、可见性和有序性。这些特性是理解和解决并发问题的基础。 1. 原子性:原子性保证了一个操作或者一系列操作在执行过程中不会被其他线程打断,即操作要么全部完成,要么全部不完成,...
Java 中的多线程机制的主要目标是解决并发问题,包括可见性、原子性和有序性三个方面。可见性问题是指一个线程对共享变量的修改,另一个线程不能立即看到。原子性问题是指一个操作或者多个操作要么全部执行并且执行...
Java提供了多种机制来确保线程安全,主要包括原子性、可见性和有序性。 **原子性**是线程安全的基础,保证了操作不会被其他线程打断。Java提供了一些原子类,如`AtomicInteger`、`AtomicLong`等,它们使用了无锁...
volatile关键字保证了变量的可见性,即一个线程对变量的修改,可以被其他线程即时看见。结合CAS,原子类能够以无锁的方式实现多线程的安全更新。 然而,CAS机制并非完美无缺,它存在几个主要问题。首先是ABA问题,...
它定义了程序中各个线程如何访问和修改共享变量,以及如何确保这些操作的可见性。在JMM中,可见性是指当一个线程修改了一个共享变量的值时,其他线程能够立即看到这个修改。 在Java中,如果没有适当的同步措施,...
volatile 变量是 Java 语言中的一种特殊变量,可以确保变量的可见性和原子性。volatile 变量可以用于实现线程安全的 comunicatoin。 5. 锁机制 锁机制是 Java 语言中的一种线程安全机制,用于保护共享资源的访问。...