volatile

volatile和synchronized

╄→гoц情女王★ 提交于 2020-01-13 03:32:16
版权声明:本文为博主原创文章,未经博主允许不得转载。 http://www.cnblogs.com/jokermo/ 0. 前言 转载请注明出处: http://www.cnblogs.com/jokermo/ volatile和synchronized都是解决多线程安全问题的方法,为了了解与使用这两个修饰符,首先需要了解什么是多线程安全问题。即多线程安全问题发生的原因。多线程安全问题产生的原因可以概括为两点: 线程任务中处理到 共享数据 。 线程任务中有多条 共享数据操作 ,一条线程在操作共享数据的过程时,另一条线程参与了运算,造成了数据错误。 解决多线程问题的思想: 只要保证多条操作共享的代码在某一时间段内被同一条线程操作,在执行期间不允许其他线程参与运算。这下就运用到了 volatile 和 synchronized 了。 1.Java内存模型简称 JMM (Java Memory Model) JMM用来屏蔽不同硬件和操作系统的内存访问差异,期望Java程序在各种平台上都能实现一致的内存访问效果。 主内存: 主内存可以简单理解为计算机当中的内存,但又不完全等同。主内存被所有的线程所共享,对于一个共享变量(比如静态变量,或是堆内存中的实例)来说,主内存当中存储了它的“本尊”。 工作内存: 工作内存可以简单理解为计算机当中的CPU高速缓存,但又不完全等同

volatile的作用

核能气质少年 提交于 2020-01-13 02:57:33
volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。   使用该关键字的例子如下:   int volatile nVint;   >>>>当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。   例如:   volatile int i=10;   int a = i;   ...   //其他代码,并未明确告诉编译器,对i进行过操作   int b = i;   >>>>volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。   >>>>注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编代码,测试有无volatile关键字

Java threading/volatile

跟風遠走 提交于 2020-01-13 02:18:44
问题 I have a thread: class Foo extends Thread { boolean active = true; public void run() { while(active) { //do stuff } } public void end() { active = false; } public void hibernate() { synchronized(this) { wait(); } } } If another thread calls end() , will Foo immediately see that active is now false ? Specifically, because active isn't volatile , I'm not sure that it will. I initially created end() as a clever way of avoiding volatile, but now I'm unsure that it will actually do what I intend.

Java threading/volatile

浪子不回头ぞ 提交于 2020-01-13 02:16:59
问题 I have a thread: class Foo extends Thread { boolean active = true; public void run() { while(active) { //do stuff } } public void end() { active = false; } public void hibernate() { synchronized(this) { wait(); } } } If another thread calls end() , will Foo immediately see that active is now false ? Specifically, because active isn't volatile , I'm not sure that it will. I initially created end() as a clever way of avoiding volatile, but now I'm unsure that it will actually do what I intend.

Java_多线程实现同步

二次信任 提交于 2020-01-13 01:56:47
多线程之间实现同步 理解线程安全 synchronized用法 死锁 Java内存模型 Vlolatile 关键字 ThreadLock 关键字 理解线程安全 什么是线程安全? 当多个线程同时对共享的同一个 全局变量或静态变量 做写的操作时 ,可能会发生数据冲突问题,也就是线程安全问题。 但是 做读操作是不会发生数据冲突问题 。 线程安全解决办法 : 使用多线程之间同步synchronized或使用锁(lock)。 原理: 同一时间内,只让当前一个线程进行对数据进行执行操作。当当前线程执行完成后释放锁,才能让其他线程进行操作执行。避免了同时对数据的操作,这样的话就可以解决线程的不安全问题,也就实现了数据的同步。 synchronized用法: synchronized有两种用法: 第一种:将可能会发生线程安全问题的代码,给包括起来,称为同步代码块。 代码如下: synchronized(锁){   //可能会发生线程冲突问题的代码块 } 第二种: 在方法上修饰synchronized,称为同步函数。 代码如下: public synchronized void 方法名() {   //可能会发生线程冲突问题的代码块 } 若在方法上加上 static 静态关键字则成为静态同步函数; 静态同步函数使用的锁是该函数所属字节码文件对象; 可以使用 getClass() 的方法获取

Java并发编程之volatile关键字

*爱你&永不变心* 提交于 2020-01-12 17:01:56
  大概是因为项目、业务的原因,工作上几乎还没有使用过多线程相关的功能,相关知识差不多都忘了,所以最近补一下基础。   volatile用来修饰共享变量,volatile变量具有 synchronized 的可见性特性,但是不具备原子特性。volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。当成员变量发生变化时,强迫线程将变化值回写到共享内存。以保证在同一时刻,不同的线程看到该成员变量的值是一致的。   因为volatile关键字与Java的内存模型有关,所以先看一下Java内存模型里面的几个概念知识。    1、可见性    指多个线程访问同一个变量时,一个线程修改了该变量的值,其他线程立马可以看到该线程修改后的值。   如下图所示,每个线程都有自己的工作内存,线程访问共享变量时,会先将变量加载到工作内存(如工作内存未缓存该变量),然后对工作内存中的变量副本进行读写操作。假设多个线程同时访问a变量,线程1修改了工作内存中的a变量值,但没有刷新到主内存中,其他线程从主内存缓存的a变量值还是原来的旧值;或者线程1修改a变量的值后刷新到了主内存,但是其他线程工作内存中缓存了线程1修改之前的旧值,其他线程访问该变量时没有从主内存中重新获取,就会出现在多个线程中,同一共享变量的值不一致,即存在可见性问题。   在 Java 中 volatile

C语言复习2

时光怂恿深爱的人放手 提交于 2020-01-12 07:36:01
/*--> */ /*--> */ 4 、 atoi() atol atof () 实现 一、atoi函数(将字符串转换成整型数) 函数说明 atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。 二、itoa(把一整数转换为字符串 ) itoa(num,str,10); num:整数 str保存位置 10:以十进制转换 三、atof(将字符串转换成浮点型数) 函数说明 atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转 换,并将结果返回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。返回值 返回转换后的浮点型数 四、atol(将字符串转换成长整型数) 函数说明 atol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。 返回值 返回转换后的长整型数。 5 、移位操作 >> << >>= <<=    位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符

干货:Java并发编程系列之volatile(二)

a 夏天 提交于 2020-01-12 06:35:53
接上一篇《Java并发编程系列之synchronized(一)》,这是第二篇,说的是关于并发编程的volatile元素。 Java语言规范第三版中对volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。 java 内存模型的核心是围绕着在并发过程中如何处理原子性、可见性、有序性这3个特性来展开的,它们是多线程编程的核心。 原子性(Atomicity): 是指一个操作是不可中断的,即使是多个线程同时执行的情况下,一个操作一旦开始,就不会被其它线程干扰。对于基本类型的读写操作基本都具有原子性的(在32位操作系统中 long 和 double 类型数据的读写不是原子性的,因为它们有64位)。 可见性(Visibility): 是指在多线程环境下,当一个线程修改了某一个共享变量的值,其它线程能够立刻知道这个修改。 有序性(Ordering): 是指程序的执行顺序是按照代码的先后顺序执行的;对于这句话如果在单线程中所有的操作都是有序的,但是在多线程环境下,一个线程的操作相对于另外一个线程的操作是无序的。 了解volatile关键字之前需要先了解下Java内存模型,java内存模型抽象示意图如下: Java内存模型 线程A和线程B之间若要通信的话, 必须经历下面两个步骤 : (1

线程三大特性以及Volatile、ThreadLocal

≯℡__Kan透↙ 提交于 2020-01-12 04:26:14
线程三大特性 多线程有三大特性,原子性、可见性、有序性。 原子性: 即单次或者单组操作要么全部执行(执行的过程不会被任何因素打断)要么就都不执行。 可见性: 即当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 有序性: 程序执行的顺序按照代码的先后顺序执行。 简单来说,原子性保证数据的一致性,是线程安全的一部分,可见性保证多线程之间共享变量的变化能够及时被其它线程发现,有序性是指在一般情况下处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但它保证程序最终执行结果和代码顺序执行的结果是一致的。 重排序对单线程并不会产生任何影响,但在多线程情况下需要考虑。 Volatile Volatile关键字的作用是修饰变量使其在多个线程之间可见,Volatile保证可见性,但是Volatile不具备原子性。 简单来说,使用Volatile关键字可以解决线程之间共享变量可见性问题, 强制线程每次读取该值的时候都去“主内存”中取值。 volatile与synchronized区别? volatile 只能修饰变量,synchronized 可修饰代码块/函数/变量,前者是轻量级的。 volatile 只能保证可见性,不具备原子性,不能用来保证线程同步安全

Is the volatile keyword required for fields accessed via a ReentrantLock?

为君一笑 提交于 2020-01-12 02:29:29
问题 My question refers to whether or not the use of a ReentrantLock guarantees visibility of a field in the same respect that the synchronized keyword provides. For example, in the following class A , the field sharedData does not need to be declared volatile as the synchronized keyword is used. class A { private double sharedData; public synchronized void method() { double temp = sharedData; temp *= 2.5; sharedData = temp + 1; } } For next example using a ReentrantLock however, is the volatile