Volatile:内存可见性】的更多相关文章

volatile两大作用 1.保证内存可见性 2.防止指令重排 此外需注意volatile并不保证操作的原子性. (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模型规定,对于多个线程共享的变量,存储在主内存当中,每个线程都有自己独立的工作内存(比如CPU的寄存器),线程只能访问自己的工作内存,不可以访问其它线程的工作内存. 工作内存中保存了主内存共享变量的副本,线程要操作这些共享变量,只能通过操作工作内存中的副本来实现,操作完毕之后再同步回到主内存当中. 如…
1.JMM:Java Memory Model(Java内存模型) 关于synchronized的两条规定: 1.线程解锁前,必须把共享变量的最新值刷新到主内存中 2.线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(注意:加锁和解锁需要是同一把锁) 注:线程解锁前对共享变量的修改在下次加锁时对其他线程可见 2.线程执行互斥代码的过程: 1.获得互斥锁 2.清空工作内存 3.从主内存拷贝变量的最新副本到工作内存 4.执行代码 5.将更改后的共享变量的值刷…
先来看一个例子: public class VolatileTest {            public static void main(String[] args) {           ThreadDemo td = new ThreadDemo();           new Thread(td).start();                while (true) {               if (td.isFlag()) {                   Sy…
1.内存可见性 ​ (程序在运行时,jvm会为每一个执行任务的线程都分配一个独立的缓存,用于提高效率) ​ 我觉得可以这样来理解: ​ 内存:啥是内存?就是可以理解成电脑当中的内存条,程序创建个变量,都放在内存当中(浅显理解) ​ 可见性:就是多个线程在运行过程中,当某一个线程对共享的变量作出修改后,其他线程能不能看到该变量是否已经被改变的现象. ​ 共享变量:线程在对该变量执行操作的时候,会从主内存中将该变量读到自己线程的缓存中去执行具体操作,执行完后再归还主内存,大家一起共享. ​ 理解了上…
先看看synchronized实现内存可见性 加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性.我们不仅希望防止某个线程正在使用对象状态而另一个线程在同时修改该状态,而且还希望确保当一个线程修改了对象状态后,其他线程能够看到该变化.而线程的同步恰恰也能够实现这一点. 内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果.为了确保所有的线程都能看到共享变量的最新值,可以在所有执行读操作或写操作的线程上加上同一把锁.下图示例了…
1.问题引入 实现线程: public class ThreadDemo implements Runnable { private boolean flag = false; @Override public void run() { flag = true; System.out.println("flag=" + flag); } public boolean isFlag() { return flag; } public void setFlag(boolean flag)…
Java多线程之内存可见性和原子性:Synchronized和Volatile的比较     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/52525724   在说明Java多线程内存可见性之前,先来简单了解一下Java内存模型.      (1)Java所有变量都存储在主内存中     (2)每个线程都有自己独立的工作内存,里面保存该线程的使用到的变量副本(该副本就是主内存中该变量的一份拷贝)    (1)线程对共…
内存可见性(Memory Visibility) 1 内存可见性(Memory Visibility)是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化. 2 可见性错误是指当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情.我们可以通过同步来保证对象被安全地发布.除此之外我们也可以使用一种更加轻量级的 volatile 变量. volatile 关…
一.原子性 原子性操作指相应的操作是单一不可分割的操作.例如,对int变量count执行count++d操作就不是原子性操作.因为count++实际上可以分解为3个操作:(1)读取变量count的当前值:(2)拿count的当前值和1做加法运算:(3)将加完后的值赋给count变量. 在多线程环境中,非原子操作可能会受其他线程的干扰.比如,上述例子如果没有对相应的代码进行同步(Synchronization)处理,则可能出现在执行第2个操作的时候,count变量的值已经被其他线程修改过了.当然,…
前言 首先,我们使用多线程的目的在于提高程序的效率,但是如果使用不当,不仅不能提高效率,反而会使程序的性能更低,因为多线程涉及到线程之间的调度.CPU上下文的切换以及包括线程的创建.销毁和同步等等,开销比单线程大,因此需谨慎使用多线程. 在jdk1.5以后,提供了一个强大的java.util.concurrent包,这个包中提供了大量的应用于线程的工具类. 下面开始介绍volatile关键字和内存可见性,虽然volatile是在jdk1.5之前就有的,但还是想放在这里讲一下. 举例说明 首先,我…