volatile

volatile 关键字

匿名 (未验证) 提交于 2019-12-02 22:56:40
内存可见性 由于 Java 内存模型( JMM )规定,所有的变量都存放在主内存中,而每个线程都有着自己的工作内存(高速缓存)。 线程在工作时,需要将主内存中的数据拷贝到工作内存中。这样对数据的任何操作都是基于工作内存(效率提高),并且不能直接操作主内存以及其他线程工作内存中的数据,之后再将更新之后的数据刷新到主内存中。 这里所提到的主内存可以简单认为是 堆内存 ,而工作内存则可以认为是 栈内存 。 如下图所示: 所以在并发运行时可能会出现线程 B 所读取到的数据是线程 A 更新之前的数据。 显然这肯定是会出问题的,因此 volatile 的作用出现了: 当一个变量被 volatile 修饰时,任何线程对它的写操作都会立即刷新到主内存中,并且会强制让缓存了该变量的线程中的数据清空,必须从主内存重新读取最新数据。 volatile 修饰之后并不是让线程直接从主内存中获取数据,依然需要将变量拷贝到工作内存中 。 内存可见性的应用 当我们需要在两个线程间依据主内存通信时,通信的那个变量就必须的用 volatile 来修饰: public class Volatile implements Runnable { private static volatile boolean flag = true ; @Override public void run ( ) { while ( flag

Volatile 关键字

允我心安 提交于 2019-12-02 22:37:50
作用 保证被 Volatile 关键字描述变量的操作具有 可见性 和 有序性 (禁止指令重排)。 注意 1、Volatile 只对基本类型 (byte、char、short、int、long、float、double、boolean) 的赋值操作和对象的引⽤赋值操作有效。 2、对于 i++ 此类复合操作, Volatile 无法保证其有序性和原子性。 3、相对 Synchronized 来说 Volatile 更加轻量一些。 来源: https://www.cnblogs.com/nachdenken/p/11765230.html

Linux 字符设备驱动―― ioremap() 函数解析

匿名 (未验证) 提交于 2019-12-02 21:59:42
一、 ioremap() 函数基础概念 几乎每一种外设都是通过读写设备上的相关寄存器来进行的,通常包括控制寄存器、状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址。根据CPU体系结构的不同,CPU对IO端口的编址方式有两种: a -- I/O 映射方式(I/O-mapped) 典型地,如X86处理器为外设专门实现了一个单独的地址空间,称为"I/O地址空间"或者"I/O端口空间",CPU通过专门的I/O指令(如X86的IN和OUT指令)来访问这一空间中的地址单元。 b -- 内存映射方式(Memory-mapped) RISC指令系统的CPU(如ARM、PowerPC等)通常只实现一个物理地址空间,外设I/O端口成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。 但是,这两者在硬件实现上的差异对于软件来说是完全透明的,驱动程序开发人员可以将内存映射方式的I/O端口和外设内存统一看作是"I/O内存"资源。 一般来说,在系统运行时,外设的I/O内存资源的物理地址是已知的,由硬件的设计决定。但是CPU通常并没有为这些已知的外设I/O内存资源的物理地址预定义虚拟地址范围,驱动程序并不能直接通过物理地址访问I/O内存资源, 而必须将它们映射到核心虚地址空间内(通过页表),然后才能根据映射所得到的核心虚地址范围

Read and Write atomic operation implementation in the Linux Kernel

China☆狼群 提交于 2019-12-02 21:59:40
Recently I've peeked into the Linux kernel implementation of an atomic read and write and a few questions came up. First the relevant code from the ia64 architecture: typedef struct { int counter; } atomic_t; #define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic64_read(v) (*(volatile long *)&(v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) #define atomic64_set(v,i) (((v)->counter) = (i)) For both read and write operations, it seems that the direct approach was taken to read from or write to the variable. Unless there is another trick somewhere, I do not understand

Is the 'volatile' keyword still broken in C#?

百般思念 提交于 2019-12-02 21:54:25
Joe Albahari has a great series on multithreading that's a must read and should be known by heart for anyone doing C# multithreading. In part 4 however he mentions the problems with volatile: Notice that applying volatile doesn’t prevent a write followed by a read from being swapped, and this can create brainteasers. Joe Duffy illustrates the problem well with the following example: if Test1 and Test2 run simultaneously on different threads, it’s possible for a and b to both end up with a value of 0 (despite the use of volatile on both x and y) Followed by a note that the MSDN documentation is

Java并发编程:volatile关键字解析

匿名 (未验证) 提交于 2019-12-02 21:53:52
Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。   volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用volatile关键字的场景。   以下是本文的目录大纲:   一.内存模型的相关概念   二.并发编程中的三个概念   三.Java内存模型   四..深入剖析volatile关键字   五.使用volatile关键字的场景   若有不正之处请多多谅解,并欢迎批评指正。   请尊重作者劳动成果,转载请标明原文链接:    http://www.cnblogs.com/dolphin0520/p/3920373.html 一.内存模型的相关概念   大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题

认识JVM性能监控与故障处理工具&深入理解Java内存模型

匿名 (未验证) 提交于 2019-12-02 21:53:52
1. 内存区,jvm的内存区,java语言的内存调试工具,jdk bin目录下的工具。 以下从《深入理解Java虚拟机》获取 名称 主要作用 jps JVM Process Status Tool, 显示指定系统内所有的HotSpot虚拟机进程 jstat JVM Statistics Monitoring Tool , 用于收集HotSpot虚拟机各方面的运行数据 jinfo Configuration Info for Java,显示虚拟机配置信息 Jmap Memory Map for Java ,生成虚拟机的内存转储快照(heapdump文件) jhat JVM Heap Dump Browser,用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户在浏览器上看到分析结果。 jstack Stack Trace for Java, 显示虚拟机的线程快照 jps命令格式: 执行结果如下: 运行代码: [java] view plain copy import public class public static void if (args[ 0 ]== null else 0 while ( true new static void "hEllo,world" int 1 , 6 char byte class 在控制台输入:java template

java面试经验小结

匿名 (未验证) 提交于 2019-12-02 21:53:52
此内容偏中高级,适合有三年经验者。 1. java中wait和sleep有什么区别?多线程条件下如何保证数据安全? 答:最大区别是等待时wait会释放锁,而sleep会一直持有锁,wait通常用于线程时交,互,sleep通常被用于暂停执行。 2. java中volatile和synchronized有什么区别? 1.volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。 2.volatile 仅能使用在变量级别; synchronized 则可以使用在变量、方法、和类级别的。 3.volatile 仅能实现变量的修改可见性,并不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性。 4.volatile 不会造成线程的阻塞; synchronized 可能会造成线程的阻塞。 5.volatile 标记的变量不会被编译器优化; synchronized 标记的变量可以被编译器优化。 3. 有了解java的原子类?实现原理是什么? 答:采用硬件提供原子操作指令实现的,即CAS。每次调用都会先判断预期的值是否符合,才进行写操作,保证数据安全。 4. spring主要使用了哪些?IOC实现原理是什么?AOP实现原理是什么?

java设计模式一单例模式

匿名 (未验证) 提交于 2019-12-02 21:53:52
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如: 1. 需要频繁实例化然后销毁的对象。 2. 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。 3. 有状态的工具类对象。 4. 频繁访问数据库或文件的对象。 应用场景举例: 1. 资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。 2. 网站的计数器,一般也是采用单例模式实现,否则难以同步。 3. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。 4. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。 单例类只能有一个实例。 单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。 public class EagerSingleton { private static EagerSingleton instance = new EagerSingleton(); /** * 私有默认构造子 */ private EagerSingleton (){} /** * 静态工厂方法 */ public

从Java多线程可见性谈Happens-Before原则

匿名 (未验证) 提交于 2019-12-02 21:53:52
Happens-Before是一个非常抽象的概念,然而它又是学习Java并发编程不可跨域的部分。本文会先阐述Happens-Before在并发编程中解决的问题―― 多线程可见性 ,然后再详细讲解Happens-Before原则本身。 Java多线程可见性 在现代操作系统上编写并发程序时,除了要注意线程安全性(多个线程互斥访问临界资源)以外,还要注意多线程对共享变量的可见性,而后者往往容易被人忽略。 可见性是指当一个线程修改了共享变量的值,其它线程能够适时得知这个修改。在单线程环境中,如果在程序前面修改了某个变量的值,后面的程序一定会读取到那个变量的新值。这看起来很自然,然而当变量的写操作和读操作在不同的线程中时,情况却并非如此。 /** *《Java并发编程实战》27页程序清单3-1 */ public class NoVisibility { private static boolean ready ; private static int number; private static class ReaderThread extends Thread { public void run () { while (! ready ) { Thread. yield (); } System.out. println (number); } } public static void