java分主内存和工作内存, 主内存是线程共享的, 工作内存是每个线程独有的. java对主内存的操作是通过工作内存间接完成的: 先拷贝主内存变量值到工作内存, 在工作内存操作这个变量的副本, 完成后将这个副本的值再写回主内存. 这几个操作不是原子性的, 意味着当有多个线程同时想修改主内存的话, 在某个线程返回变量副本之前, 主内存的值相对于这个线程获得的主内存的值已经发生, 那么基于旧值得操作必然是错误的. 这就是java并发问题的根本原因. 8种基本原子操作(个人理解): lock unlo…
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt202 Java内存模型:volatile是干什么用的Volatile字段是用于线程间通讯的特殊字段.每次读volatile字段都会看到其它线程写入该字段的最新值:实际上,程序员之所以要定义volatile字段是因为在某些情况下由于缓存和重排序所看到的陈旧的变量值是不可接受的.编译器和运行时禁止在寄存器里面分配它们.它们还必须保证,在它们写好之后,它们被从缓冲区刷新到主存中,…
1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部执行并且执行过程中不会被打断,要么都不执行. 一个经典的例子就是银行转账:从账户A向账户B转账1000元,此时包含两个操作:账户A减去1000元,账户B加上1000元.这两个操作必须具备原子性才能保证转账安全.假如账户A减去1000元之后,操作被打断了,账户B却没有收到转过来的1000元,此时就出问…
Java内存模型与volatile关键字 一).并发程序开发 并行程序的开发要涉及多线程.多任务间的协作和数据共享问题. 常用的并发控制:内部锁.重入锁.读写锁.信号量. 二).线程的特点 线程的特点: 1).每一个线程都有一块工作内存区,存放所有线程共享的主内存中变量值的拷贝. 2).当程序执行时,它在自己的工作内存中操作这些变量. 3).线程操作,先获取锁定并清除它的工作内存,重新将共享内存区正确的装入线程 ​ 的工作内存区. 4).线程解锁,将线程工作内存区的值重新写回共享内存中. 注:线…
 Java的内存模型 Java内存模型(JMM)是一个抽象的模型.决定了线程主要定义了线程和内存间的抽象关系:主内存存放的是线程共享变量,每个线程有自己的工作内存,存放变量的副本,只能对副本进行读写,副本的变量再刷新到主内存中.具体体现为多核CPU,每核有一个高速缓存,每个核的线程对高速缓存读写,并且有共同的主存. 主内存与工作线程交互的操作有以下八种: lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态unlock(解锁):作用于主内存的变量,释放锁定状态的变量read…
volatile作用总结: 1. 强制线程从公共内存中取得变量的值,而不是从线程的私有的本地内存中,volatile修饰的变量不具有原子性(修改一个变量的值不能同步). 2. 保证volatile修饰的变量在被一个线程修改后,会被强制立即刷新到主存(可见性),其他线程如果有该变量的缓存行,会被设置为无效. 3. 禁止指令重排(有序性). a.happen-before b.编译器在生成字节码时, 会在指令序列中插入内存屏障,会多出一个 lock 前缀指令 内存屏障是一组处理器指令,解决禁止指令重…
多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”.可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值. 它在某些情况下比synchronized的开销更小,本文将深入分析在硬件层面上Inter处理器是如何实现Volatile的,通过深入分析能帮助我们正确的使用Volatile变量.   术语定义 术语 英文单词   描述 共享变量   在多个线程之…
1.众所周知,java的内存模型是一个主内存,每个线程都有一个工作内存空间,那么主内存同步到工作内存是什么时候发生的呢?工作内存同步会主内存又是什么时候发生的呢? 在cpu进行线程切换时就会发生这些同步吗?那如果是多核cpu呢,多个核心间没有线程切换,那么内存同步是在什么时候发生的呢? 多个cpu核心共享同一片内存区域,但是cpu的缓存并不是共享的,jvm是个虚拟的计算机,把底层抽象化到jvm内部了,那么jvm内部的内存同步是在什么时候进行的呢? 2.volatile关键的作用究竟是什么? 已知…
volatile 的特性 当我们声明共享变量为 volatile 后,对这个变量的读/写将会很特别.理解 volatile 特性的一个好方法是:把对 volatile 变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步.下面我们通过具体的示例来说明,请看下面的示例代码: class VolatileFeaturesExample { //使用volatile声明64位的long型变量 volatile long vl = 0L; public void set(long l) {…
volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个监视器锁对这些单个读/写操作做了同步.下面我们通过具体的示例来说明,请看下面的示例代码: class VolatileFeaturesExample { volatile long vl = 0L; //使用volatile声明64位的long型变量 public void set(long l) { vl =…