并发编程 — volatile

volatile是一个被遗忘的关键字,在开发串行程序当中不会使用,而并行程序当中也不能代替锁(synchronized)(大多数情况下).但开发当中若然巧妙使用volatile,将避免不必要的加锁操作.

在并行程序开发当中操作变量需要注意两个问题.一个是安全性(正确性),另一个是内存可见性.当多个线程同时操作一个变量时,可以使用锁来保证操作变量的安全性和内存可见性,但若然当操作结果不需要依赖上一个结果,而仅仅只作为一个标识,则可以使用volatile来代替加锁.

以下代码不需要线程安全性,仅仅将变量作为退出线程的标识.但遗憾的是该程序有可能永远无法退出.

Java代码  

  1. public class Application {
  2. private static boolean flag = false;
  3. private static int number;
  4. public static void main(String[] args) throws InterruptedException {
  5. new Test().start();
  6. Thread.sleep(1000);
  7. number = 50;
  8. flag = true;
  9. }
  10. private static class Test extends Thread {
  11. @Override
  12. public void run() {
  13. while (!flag) {
  14. System.out.println(number);
  15. }
  16. }
  17. }
  18. }

volatile是Java提供的一种稍弱的同步机制,用来增大被修饰变量的内存可见性,从而达到将变量的更新操作通知到其他线程.若然访问volatile修饰的变量将会到主存(堆)当中获取.而不会读取线程的变量副本,被修饰的变量亦不会被缓存到寄存器或者对其他处理器不可见的地方.volatile只承诺被修饰变量的内存可见性,而不保证变量是否被正确的操作,因此volatile从语义或使用上都不能替代锁.因此当遇到以下场景时,可考虑使用volatile. 
1.对变量的操作不依赖变量的当前值. 
2.能确保只有一个线程对其进行修改. 
3.修改变量不影响程序正确性.

总结: 
      在某些情况下使用volatile能避免不必要的加锁操作,尽管有更多或更好的方案代替volatile,但亦可以了解这个关键字的使用方法,必要时多一套解决方案.而在性能方面对比加锁的线程挂起/恢复开销,每次访问变量都需要去主存获取的volatile可以说是忽略不计.

时间: 2024-10-11 07:23:34

并发编程 — volatile的相关文章

6.并发编程--volatile

并发编程--volatile volatile-说明 volatile关键字的作用是变量在多个线程可见: volatile 关键字是非原子性的 要是实现原子性操作,建议使用atomic类的系列对象:支持原子性操作(注意atomic类只保证本身方法的原子性,并不保证多次操作的原子性) 1. volatile : volatile关键字的作用是变量在多个线程可见: 示例:RunThread.java说明:在Java中,每个线程都会有一个工作内存区域,其中存放所有线程共享的主内存中的变量的值得拷贝.当

Java并发编程 Volatile关键字解析

volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的. 2)禁止进行指令重排序. 根据volatile的语义,我们可以看到,volatile主要针对的是并发三要素(原子性,可见性和有序性)中的后两者有实际优化作用. 可见性: 线程本身并不直接与主内存进行数据的交互,而是通过线程的工作内存来完成相应的操作.

java并发编程 -volatile关键字

java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他的线程. 当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序,volatile变量 不会被缓存在寄存器或者对处理器不可见的地方,因此在读取volatile变量时总会返回最新写入的值.访问volatile变量不会执行加锁操作,因此也就不会使得执行线程阻塞,因此volatile变量是一种比sychronized关键字更加轻量级的

Java并发编程-volatile

一. volatite 简述Java 语言提供了一种稍弱的同步机制,即 volatile 变量.用来确保将变量的更新操作通知到其他线程,保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新. 当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的.二. volatite 线程安全?volatile 变量对所有线程是立即可见的,对 volatile 变量所有的写操作都能立即反应到其他线程之中,换句话说: volatile 变量在各个线程中是一致的,所以基于 vola

Java并发编程--Volatile详解

摘要 Volatile是Java提供的一种弱同步机制,当一个变量被声明成volatile类型后编译器不会将该变量的操作与其他内存操作进行重排序.在某些场景下使用volatile代替锁可以减少代码量和使代码更易阅读.   Volatile特性 1.可见性:当一条线程对volatile变量进行了修改操作时,其他线程能立即知道修改的值,即当读取一个volatile变量时总是返回最近一次写入的值 2.原子性:对于单个voatile变量其具有原子性(能保证long double类型的变量具有原子性),但对

Java并发编程-volatile可见性的介绍

前言 要学习好Java的多线程,就一定得对volatile关键字的作用机制了熟于胸.最近博主看了大量关于volatile的相关博客,对其有了一点初步的理解和认识,下面通过自己的话叙述整理一遍. 有什么用? volatile主要对所修饰的变量提供两个功能 可见性 防止指令重排序 <br>本篇博客主要对volatile可见性进行探讨,以后发表关于指令重排序的博文. 什么是可见性? 一图胜千言上图已经把JAVA内存模型(JMM)展示得很详细了,简单概括一下 每个Thread有一个属于自己的工作内存(

并发编程--CAS自旋锁

在前两篇博客中我们介绍了并发编程--volatile应用与原理和并发编程--synchronized的实现原理(二),接下来我们介绍一下CAS自旋锁相关的知识. 一.自旋锁提出的背景 由于在多处理器系统环境中有些资源因为其有限性,有时需要互斥访问(mutual exclusion),这时会引入锁的机制,只有获取了锁的进程才能获取资源访问.即是每次只能有且只有一个进程能获取锁,才能进入自己的临界区,同一时间不能两个或两个以上进程进入临界区,当退出临界区时释放锁.设计互斥算法时总是会面临一种情况,即

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

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用vola

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

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用vola