volatile

关于jdk中的AtomicInteger的操作

匿名 (未验证) 提交于 2019-12-03 00:18:01
private volatile int value; 这里的valueOffset 指的是value值相对于AtomicInteger对象首地址的在内存中偏移量,根据这个地址可以准确的定位value的值。 volatile 可以保证不同线程下的内存可见性, getAndIncrement的操作相当于一个乐观锁,每次进行i++操作前先获取到原来的value值,最终进行改变数据时,比较当前所持有的value值和原来的value值 current 是否一致,如果一致会进行修改值的操作。不一致的情况下会循环调用进行比较(随之带来的就是性能问题,会一直进行死循环,直到修改完value中的值) public final boolean compareAndSet(int expect, int update) { 主要传入当前的值this 和valueOfferset,这样可以定位到原本的value值,和excepte进行比较,如果线程不安全,就返回false.如果线程安全,将update的值赋给value. 文章来源: 关于jdk中的AtomicInteger的操作

04 volatile关键字实现原理

匿名 (未验证) 提交于 2019-12-03 00:14:01
作用:让其他线程能够马上感知到某个线程多某个变量的修改 保证可见性 对共享变量的修改,其他线程能够马上感知到 保证有序性 在重排序时保证volatile修饰的代码位置不变 实现原理 对于volatile修饰的变量会编译时会使用Lock指令,其他线程用到Lock指令修饰的变量时会从主存中直接获取 状态标志(开关模式) 一个线程通过改变共享变量的值,来控制另一个现实的结束 双重检查锁定(double-checked-locking) DCL 懒汉式单例 需要利用顺序性 使用上 volatile修饰变量,synchronized修饰方法和语句块 对原子性的保证 synchronized保证了原子性,volatile不能保证原子性 可见性的保证 都可以保证,但原理不同 volatile对变量加lock,synchronized使用monitorEnter和monitorExit 对有序性的保证 volatile禁止了重排序,保证了有序性 sychronized是通过加重量级锁将并行退化成串行,容易引起阻塞 来源:博客园 作者: YL10000 链接:https://www.cnblogs.com/lifeone/p/11653133.html

volatile实现原理

匿名 (未验证) 提交于 2019-12-03 00:03:02
从内存中把数据读到Cache 在Cache中更新数据 把Cache中数据更新到内存 MESI() 读操作:不做任何事情,把Cache中的数据读到寄存器 写操作:发出信号通知其他的CPU将该变量的Cache line置为无效,其他的CPU要访问这个变量的时候,只能从内存中获取。 Cache line CPU的cache中会增加很多的Cache line 主内存数据所有线程都可以访问(共享变量) 每个线程都有自己的工作空间(本地内存) 工作空间:局部变量、主内存的副本 线程不能直接修改主内存的数据,只能将数据读到工作空间,修改完刷新到主内存 对共享变量的修改,可以让其他线程感知到。 不能保证原子性。 使用lock锁; 当某个线程将volatile修饰的变量改变的时候,会将该变量的Cache line置为失效; 其他线程感知到Cache Line失效,会重新去主存获取该变量。 lock是汇编中的指令; Cache line是硬件中的指令。 编译阶段、cpu指令优化阶段; 代码顺序并不是实际的执行顺序。 volatile修饰的变量位置不变 (即volatile前的代码不能放到volatile之后,volatile后的代码不能放到volatile之前) 加了轻量锁Lock volatile只能修饰变量,synchronized只能修饰方法和代码块 volatile不能保证原子性

面试必问的并发编程知识点,你知道多少?

匿名 (未验证) 提交于 2019-12-02 23:57:01
前言 众所周知,在Java的知识体系中,并发编程是非常重要的一环,也是面试的必问题,一个好的Java程序员是必须对并发编程这块有所了解的。 然而不论是哪个国家,什么背景的 Java 开发者,都对自己写的并发程序相当自信,但也会在出问题时表现得很诧异甚至一筹莫展。 可见,Java 并发编程显然不是一件能速成的能力,基础搭得越好,越全面,在实践中才会有更深刻的理解。 因此,大家不难发现 Java 并发问题一直是各个大厂面试的重点之一。我在平时的面试中,也发现很多候选人对一些基本的并发概念表示没听过,或原理不理解,可能知道一些却又讲不清楚,最终导致面试失败。 本文会结合实际中接触到的一些面试题,重点来聊一聊 Java 并发中的相关知识点。 Synchronized 相关问题 问题一:Synchronized 用过吗,其原理是什么? 问题二:你刚才提到获取对象的锁,这个“锁”到底是什么?如何确定对象的锁? 问题三:什么是可重入性,为什么说 Synchronized 是可重入锁? 问题四:JVM 对 Java 的原生锁做了哪些优化? 问题五:为什么说 Synchronized 是非公平锁? 问题六:什么是锁消除和锁粗化? 问题七:为什么说 Synchronized 是一个悲观锁?乐观锁的实现原理又是什么?什么是 问题八:乐观锁一定就是好的吗? 可重入锁 ReentrantLock

How to properly access mapped memory without undefined behavior in C++

浪尽此生 提交于 2019-12-02 23:54:55
I've been trying to figure out how to access a mapped buffer from C++17 without invoking undefined behavior. For this example, I'll use a buffer returned by Vulkan's vkMapMemory . So, according to N4659 (the final C++17 working draft), section [intro.object] (emphasis added): The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is created by a definition (6.1), by a new-expression (8.3.4), when implicitly changing the active member of a union (12.3), or when a temporary object is created (7.4, 15.2). These are, apparently, the only valid ways to

volatile 和 内存屏障

匿名 (未验证) 提交于 2019-12-02 23:52:01
volatile OpenJDK unsafe.cpp volatile lock: Lock Lock Lock CPU CPU Lock CPU里 缓存了该地址的数据无效 Thread-A与Threab-B同时操作主存中的一个volatile变量i时,Thread-A i Thread-A发出 LOCK#指令 LOCK#指令 锁总线(或锁缓存行) CPU不能访问总线 ,不能访问总线就意味着 不能访问系统内存 )Thread-B高速缓存中的 Thread-A向主存回写最新修改的i Thread-B读取变量i,那么: Thread-B发现对应地址的 volatile关键字的读和普通变量的读取相比基本没差别,差别主要还是在变量的写操作上。 为什么 static volatile int i = 0; i++;不保证线程安全? i++并不是一个原子操作 i++本身特质决定的 1、 获取 i 2、i自增 3、回写i A、B两个线程同时自增i 由于 volatile可见性,因此步骤1ii 2步开始就有问题了,有可能出现的场景是线程A自增了i并回写,但是线程B此时已经拿到了i,不会再去拿线程A回写的i,因此对原值进行了一次自增并回写 A对i进行自增了以后cpu缓存不是应该通知其他缓存,并且重新load i么? A对i进行了自增,线程B已经拿到了i并不存在需要再次读取i的场景

torch.no_grad

匿名 (未验证) 提交于 2019-12-02 23:48:02
requires_grad Variable变量的requires_grad的属性默认为 False ,若一个节点requires_grad被设置为True,那么所有依赖它的节点的requires_grad都为True。 x=Variable(torch.ones(1)) w=Variable(torch.ones(1),requires_grad=True) y=x*w x.requires_grad,w.requires_grad,y.requires_grad Out[23]: (False, True, True) y依赖于w,w的requires_grad=True,因此y的requires_grad=True (类似or操作) volatile volatile=True是Variable的另一个重要的标识,它能够将所有依赖它的节点全部设为volatile=True, 其优先级比requires_grad=True高 。因而volatile=True的节点不会求导,即使requires_grad=True,也不会进行反向传播,对于不需要反向传播的情景(inference,测试推断),该参数可以实现一定速度的提升,并节省一半的显存,因为其不需要保存梯度 前方高能预警 :如果你看完了前面volatile,请及时把它从你的脑海中擦除掉,因为 UserWarning:

多线程--volatile

匿名 (未验证) 提交于 2019-12-02 23:47:01
1. volative特点是提供可见性, 没有提供互斥性 (synchronized有互斥性)。 因此,volatile 在 多线程并发修改 某个变量时依然会 出现并发问题 。 2.使用的场景是:一个线程 修改 被volatile修饰的变量,其他的线程 获取 这个变量的值。 建议: 当 多个线程并发修改某个变量 的时候,必须使用synchronized来进行 互斥同步

May accesses to volatiles be reordered?

我是研究僧i 提交于 2019-12-02 23:43:34
Consider the following sequence of writes to volatile memory, which I've taken from David Chisnall's article at InformIT , "Understanding C11 and C++11 Atomics": volatile int a = 1; volatile int b = 2; a = 3; My understanding from C++98 was that these operations could not be reordered, per C++98 1.9: conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below ... The observable behavior of the abstract machine is its sequence of reads and writes to volatile data and calls to library I/O functions Chisnall says that the constraint

volitile的使用

匿名 (未验证) 提交于 2019-12-02 23:05:13
volatileche称为轻量级锁,被volatile修饰的变量,在线程之间是可见的。 可见:一个线程修改了这个变量的值,在另一个线程中能够读到这个修改后的值 synchronized除了线程之间互斥,还有一个非常大的作用,就是保证可见性 1 /* 2 * 保证可见性的前提 3 * 4 * 多个线程拿到同一把锁,否则保证不了 5 * 6 */ 7 public class Demo { 8 private int a = 1; 9 10 public synchronized int getA() { 11 return a; 12 } 13 14 public synchronized void setA(int a) { 15 try { 16 Thread.sleep(10); 17 } catch (InterruptedException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 this.a = a; 22 } 23 24 public static void main(String[] args) { 25 Demo demo = new Demo(); 26 27 new Thread(new Runnable() { 28 29 @Override 30