volatile

C语言中的volatile——让我保持原样

房东的猫 提交于 2019-12-06 15:24:11
volatile译为:易变的。这不是和题目的让我保持原样矛盾了吗?其实不然,在变量前加上该关键字修饰,确实是告诉编译器,这个变量是一个容易改变的变量,不要对它进行优化,每次都要到变量的地址中去读取变量的数据,但正因为这样,才是保持了变量的原样,因为变量已经发生改变了,你却操作的是没有变化时的数据,这样才让变量失去了本应该保持的属性。 eg: int a=1; a=2; a=3; .... 编译器看到这样的代码,会觉得a的值只有a=3才有意义,所以把a存储在一个寄存器中,每次遇到a都在这个寄存器中去读取数据,但是a是可能改变,比如中断或者多线程的时候。这个有可能你测试它又是正确的,因为随着你的优化等级提高,生成的汇编代码会有很大不同,如果基础不够扎实,代码的鲁棒性就会减弱,要想不这样,那么需要程序员有足够扎实的基本功。 1.我们先看volatile第一个应用场景,在中断服务函数中的使用。 /* main.c */ int flag=0; int main(void) {   if(flag==1)     {do somethings}   if(flag==2)    {do somethings}   return 0; } /* interrupt*/ void NVIC_Handler(void) {   flag=1; } 在这种情况下,编译器可能会对其做优化

Java: how volatile guarantee visibility of “data” in this piece of code?

两盒软妹~` 提交于 2019-12-06 15:06:19
问题 Class Future { private volatile boolean ready; private Object data; public Object get() { if(!ready) return null; return data; } public synchronized void setOnce(Object o) { if(ready) throw...; data = o; ready = true; } } It said "if a thread reads data, there is a happens-before edge from write to read of that guarantees visibility of data" I know from my learning: volatile ensures that every read/write will be in the memory instead of only in cache or registers; volatile ensures reorder:

Java并发多线程面试题 Top 50

吃可爱长大的小学妹 提交于 2019-12-06 14:36:22
不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者精通多线程技术并且有丰富的Java程序开发、调试、优化经验,所以线程相关的问题在面试中经常会被提到。 在典型的Java面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程, 如何创建线程,用什么方式创建线程比较好(比如: 继承thread类还是调用Runnable接口 ),然后逐渐问到并发问题像在Java并发编程的过程中遇到了什么挑战,Java内存模型,JDK1.5引入了哪些更高阶的并发工具,并发编程常用的 设计模式 ,经典多线程问题如生产者消费者,哲学家就餐,读写器或者简单的有界缓冲区问题。仅仅知道线程的基本概念是远远不够的, 你必须知道如何处理 死锁 , 竞态条件 ,内存冲突和线程安全等并发问题。掌握了这些技巧,你就可以轻松应对多线程和并发面试了。 许多Java程序员在面试前才会去看面试题,这很正常。因为收集面试题和练习很花时间,所以我从许多面试者那里收集了Java多线程和并发相关的50个热门问题。我只收集了比较新的面试题且没有提供全部答案。想必聪明的你对这些问题早就心中有数了, 如果遇到不懂的问题,你可以用Google找到答案。若你实在找不到答案,可以在文章的评论中向我求助

volatile

北战南征 提交于 2019-12-06 14:34:53
Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized ”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。 锁提供了两种主要特性: 互斥(mutual exclusion) 和 可见性(visibility) 。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。 Volatile 变量 Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。因此,单独使用 volatile 还不足以实现计数器

java内存模型

穿精又带淫゛_ 提交于 2019-12-06 12:21:41
一、计算机的高速缓存模型 现在的计算机基本都是多核的,比如我用的8核,上图只有两核。数据最根本当然是存储再硬盘上的,但是硬盘的读取速度很慢。所以都是先将程序运行的数据加载到内存条(RAM中)的。早期的计算机,CPU和RAM是直接交互的,因为早期的CPU的性能还不像现在这样,非常好。有一个叫做摩尔定律的,大概的意思是说现在的科技发展,每间隔18个月,CPU的性能会翻一倍。慢慢的CPU的性能就比RAM高出很多了,这样导致RAM不能很好的发挥CPU的性能。现在的计算机大多都再CPU和RAM之间加了一个CPU高速缓存。但是这个缓存非常贵...如果打开任务管理器,是可以看到的,如下图 二、JMM JAVA内存模型 了解CPU高速缓存模型是因为JMM和它很像,RAM中存放的是一些程序变量。多个线程可能会共享变量。每个线程都有自己额工作内存。共享变量其实是先复制到工作内存中给线程用,最后再线程操作ok后再保存回去的。但是线程A,B,C如果共享了同一个变量,再不做任何代码级别的操作的时候,他们之间的共享变量副本是不会互相感知的,这个时候就可能出现线程安全相关的问题了。比如下面的代码示例 package com.lyb.jmm; /** * @ClassName Jmm * @Description * @Author Lyb * @Date 2019/12/4 13:48 * @Version

全面理解Java内存模型

不羁岁月 提交于 2019-12-06 10:44:53
------------恢复内容开始------------ 1. java内存模型即java Memory Model,简称JMM.JMM定义了Java虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的。 2.并发编程有两个关键问题: 线程之间的通信和同步 。 3.线程之间的 通信 机制有两种: 共享内存和消息传递 。 1)在 共享内存 的并发模型里,线程之间共享程序的公共状态,线程之间通过写读内存中的公共状态来 隐式 进行通信,典型的共享内存通信方式就是通过共享对象进行通信。 2)在 消息传递 的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来 显式 进行通信,在Java中典型的消息传递方式是wait()和notify() 4.线程之间的 同步 是指程序用于控制不同线程之间操作发生相对顺序的机制。 1)在 共享内存 并发模型里,同步是 显式 进行的。必须显式指定某个方法或某段代码需要在线程之间互斥执行。 2)在 消息传递 的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是 隐式 进行的。 5.Java的并发采用的是 共享内存模型 ,即Java内存模型(简称JMM), JMM决定一个线程对共享变量的写入合适对另一个线程可见 。从抽象的角度来看, JMM定义了线程和主内存之间的抽象关系

面试问题

最后都变了- 提交于 2019-12-06 08:50:13
-----2019-12-2 1、Volatile关键字的粗浅理解 在学习并发编程的时候了解到,volatile关键字有两个作用: 1. 并发环境可见性:volatile修饰后的变量能够保证该变量在线程间的可见性,线程进行数据的读写操作时将绕开工作内存(CPU缓存)而直接跟主内存进行数据交互,即线程进行读操作时直接从主内存中读取,写操作时直接将修改后端变量刷新到主内存中,这样就能保证其他线程访问到的数据是最新数据 2. 并发环境有序性:通过对volatile变量采取内存屏障(Memory barrier)的方式来防止编译重排序和CPU指令重排序,具体方式是通过在操作volatile变量的指令前后加入内存屏障,来实现happens-before关系,保证在多线程环境下的数据交互不会出现紊乱 Volatile无法保证原子性 由于volatile关键字的可见性,导致容易被误解其作用,以下描述是不准确的:“volatile变量对所有线程是立即可见的,对volatile变量所有的写操作都能立即反馈到其他线程中,volatile变量在各个线程中都是一致的,所以基于volatile变量的运算在并发下安全的” 使用volatile关键字虽然能够使线程共享的变量在并发情况下完全可见,起到线程信息交互和通信的作用,但对于非原子操作,volatile并不能保证该操作的原子性

IPC via mmap'ed file: should atomics and/or volatile be used?

拥有回忆 提交于 2019-12-06 08:27:28
I use a mmap'ed file to share data between processes. The code is like this: struct Shared { int Data; }; int file = open("file.dat", O_RDWR); Shared* shared = static_cast<Shared*>( mmap(0, sizeof(Shared), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, file, 0)); shared->Data++; The questions are: Should I use volatile qualifier ( volatile int Data )? Should I use atomic operations on the shared data ( __sync_fetch_and_add(&(shared->Data), 1) )? For future reference: Volatile: Almost Useless for Multi-Threaded Programming . You should not use volatile when changing an integer from more

how does the volatile count++ operation be made thread safe

感情迁移 提交于 2019-12-06 07:47:31
问题 I have been going through JCIP and there the author says.. A special case of thread confinement applies to volatile variables. It is safe to perform read-modify-write operations on shared volatile variables as long as you ensure that the volatile variable is only written from a single thread For instance count++ is considered a compound operation (reading the value,adding one to it,and updating the value) and declaring count as volatile does not make this operation atomic, so thread safety is

单例模式学习

半世苍凉 提交于 2019-12-06 06:43:27
请参考  https://blog.csdn.net/javazejian/article/details/71333103 以单例模式来说,最普通的是饿汉式,这种模式在类被加载时就会创建该单例所需要的全部资源,比较耗时间。 懒汉式在多线程访问情况下可能会出现多次创建对象的情况,需要做同步处理 public class Singleton { private static volatile Singleton singleton=null; private Singleton(){} public static Singleton getInstance(){ if(singleton==null){ synchronized (Singleton.class){ if(singleton==null){ singleton=new Singleton(); } } } return singleton; } } 使用双重检查锁的方式。volatile关键字的语义 该关键字有两层语义。第一层语义是可见性,可见性是指在一个线程中对该变量的修改会马上由工作内存(Work Memory)写回主内存(Main Memory),所以其它线程会马上读取到已修改的值,关于工作内存和主内存可简单理解为高速缓存(直接与CPU打交道)和主存(日常所说的内存条),注意工作内存是线程独享的