volatile

浅谈volatile关键字

匿名 (未验证) 提交于 2019-12-02 21:40:25
volatile是一种轻量级的同步机制。它可以 保证内存可见性 以及 防止指令重排序 ,但是 不保证原子性 volatile和JMM机制是不可分割的,在谈volatile的时候有必要先了解以下JMM JMM(Java内存模型) JMM是一种抽象的概念模型,实际上并不存在。JMM主要可以将内存看成两块,一块是主内存,用于存放共享变量,线程间共享。 一块是线程私有的工作内存,存放变量副本。每次线程生成的时候都会创建一个私有的工作内存。当线程要操作主内存中的共享 变量的时候需要先将变量复制到自己的工作内存中,在工作内存中对变量副本进行操作,操作完成后再同步回主内存。 简单了解了JMM后我们就深入了解一下volatile是如何保证内存可见性,禁止指令重排序,又是为什么不保证原子性 内存可见性 由JMM模型我们可以看到,每个线程都是再各自的工作内存中进行工作,它们只知道自己把变量改成什么样了,并不知道其他线程把 变量改成什么样子了。这样会出现一种问题:假设主内存中有变量a的值为0,线程A读取变量a并且copy一份副本到自己的工作内存, 线程B也读取变量a且cope一份副本到自己的工作内存,线程A给变量a加上10,线程B给变量a加上20。那么我们期望的结果是最终主 内存中的变量a的值被同步成了30.但是由于线程A和线程B并不知道对方所作的修改,必定有一方将自己的变量副本同步进主内存的时

Java基础之volatile详解

匿名 (未验证) 提交于 2019-12-02 21:35:18
Java基础之volatile详解 目录: 什么是volatile? JMM内存模型之可见性 volatile三大特性之一:保证可见性 volatile三大特性之二:不保证原子性 volatile三大特性之三: 禁止指令重排 小结 1. 什么是volatile? 答:volatile是java虚拟机提供的轻量级的同步机制(可以理解成乞丐版的synchronized) 特性有: 保证可见性 不保证原子性 禁止指令重排 理解volatile特性之一保证可见性之前要先理解什么是JMM内存模型的可见性 2. JMM内存模型之可见性 JMM(Java内存模型Java Memory Model,简称JMM)本身是一种抽象的概念 并不真实存在 ,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。 JMM关于同步的规定: 线程解锁前,必须把共享变量的值刷新回主内存 线程加锁前,必须读取主内存的最新值到自己的工作内存 加锁解锁是同一把锁 由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域,而Java内存模型中规定所有变量都 存储在主内存 ,主内存是共享内存区域,所有线程都可以访问, 但线程对变量 的操作(读取赋值等)必须在工作内存中进行

JAVA中的volatile关键字

匿名 (未验证) 提交于 2019-12-02 21:35:04
JAVA提供了volatile关键字,用于修饰变量。 1.保证变量对所有线程的可见性 当一个线程修改了变量的值,会强制同步到内存,这样其它线程能够立即读取它的值。 2.禁止指令重排 通过插入内存屏障禁止CPU重新排序指令。 volatile翻译为:不稳定的、易变的; 含义可以理解为:变量的值可能随时会别的线程修改,保证其它线程能读取到修改后的值。 volatile能具备可见性、有序性,但不具备原子性。 适用场景: 线程循环标志位变量; 单例模式中的实例变量; 读多写少,写操作不依赖当前值。 JDK中应用: ConcurrentHashMap的Entry的value和next被声明为volatile; AtomicLong中的value被声明为volatile。 对比synchronized关键字: volatile不具体原子性,因此不能保证多线程读写数据时数据的一致性; 但它不阻塞线程,性能高于synchronized。 当对非volatile变量进行读写的时候,每个线程先从内存拷贝变量到CPU缓存; 如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着变量可能拷贝到不同的CPU缓存; 指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。 指操作的最小单位,是不可分割的。 例: 原子性操作 a=0; 非原子性 a++; 指令是按顺序串行执行的。

Does Monitor.Wait ensure that fields are re-read?

冷暖自知 提交于 2019-12-02 21:23:57
It is generally accepted (I believe!) that a lock will force any values from fields to be reloaded (essentially acting as a memory-barrier or fence - my terminology in this area gets a bit loose, I'm afraid), with the consequence that fields that are only ever accessed inside a lock do not themselves need to be volatile . (If I'm wrong already, just say!) A good comment was raised here , questioning whether the same is true if code does a Wait() - i.e. once it has been Pulse() d, will it reload fields from memory, or could they be in a register (etc). Or more simply: does the field need to be

volatile variables and memory barrier in java

梦想与她 提交于 2019-12-02 21:15:29
I've got a data structure which consists of linked nodes. You can think of it as of a simple LinkedList. Each node of the list consists of some value and a next field pointing the other node or null if it is the last node. The first node works as a root, it has no value it only points to the next node. All the other nodes are practically immutable that is once they are created neither their value nor their next field change during lifetime, unless the structure is being disposed which relates to a specific situation. One (only one) thread adds new nodes to the front of the list. It is

java.util.concurrent概述

匿名 (未验证) 提交于 2019-12-02 20:59:24
简称juc,是一个在并发编程中有用的包,有5部分内容: 1.atomic 这个方法底层用CAS实现,这个方法参数expectedValue是一个旧的预期值,updateValue是更新后的新值,如果内存中的值和expectedValue相等,就把内存中的值更新为updateValue,然后返回true,否则不更新内存的值,返回false;这是一个比较和交换的过程,为什么它是原子性的呢?因为硬件指令集的发展,比较并交换(Compare-And-Swap)在语义上看起来需要多次操作的行为,但是只需要通过一条处理器指令就可以完成,所以他是原子性的,这类指令还有: 测试并设置(Test-And-Set) 获取并增加(Fetch-And-Increment) 加载链接/条件存储(Load-Linked/Store-Conditional,LL/SC) 原子性的访问和更新遵循volatile原则: get 获得volatile修饰的变量的内存值 set 赋值volatile修饰的变量的内存值 lazySet 最终赋值,不能防止重排序; weakCompareAndSet 原子性的读和有条件的写,与compareAndSet的底层实现相同; 除了修饰单个变量外,还能提供了以Updater命名的类,这些类可以对任何类的任何volatile修饰的字段做compareAndSet操作

“pseudo-atomic” operations in C++

人走茶凉 提交于 2019-12-02 20:58:09
So I'm aware that nothing is atomic in C++. But I'm trying to figure out if there are any "pseudo-atomic" assumptions I can make. The reason is that I want to avoid using mutexes in some simple situations where I only need very weak guarantees. 1) Suppose I have globally defined volatile bool b, which initially I set true. Then I launch a thread which executes a loop while(b) doSomething(); Meanwhile, in another thread, I execute b=true. Can I assume that the first thread will continue to execute? In other words, if b starts out as true, and the first thread checks the value of b at the same

Is the popular “volatile polled flag” pattern broken?

瘦欲@ 提交于 2019-12-02 20:47:07
Suppose that I want to use a boolean status flag for cooperative cancellation between threads. (I realize that one should preferably use CancellationTokenSource instead; that is not the point of this question.) private volatile bool _stopping; public void Start() { var thread = new Thread(() => { while (!_stopping) { // Do computation lasting around 10 seconds. } }); thread.Start(); } public void Stop() { _stopping = true; } Question : If I call Start() at 0s and Stop() at 3s on another thread, is the loop guaranteed to exit at the end of the current iteration at around 10s? The overwhelming

How can assigning a variable result in a serious performance drop while the execution order is (nearly) untouched?

别来无恙 提交于 2019-12-02 20:36:43
When playing around with multithreading, I could observe some unexpected but serious performance issues related to AtomicLong (and classes using it, such as java.util.Random), for which I currently have no explanation. However, I created a minimalistic example, which basically consists of two classes: a class "Container", which keeps a reference to a volatile variable, and a class "DemoThread", which operates on an instance of "Container" during thread execution. Note that the references to "Container" and the volatile long are private, and never shared between threads (I know that there's no