zoukankan      html  css  js  c++  java
  • 多线程——volatile

    在多线程中,为了使得某个变量对任意一个线程可见,会使用volatile对该变量进行修饰。

            理解volatile之前,要先知道线程是如何调用变量的。每一个线程都拥有自己的一个私有堆栈,变量是定义在主内存中,而每个线程会将变量copy一份到私有堆栈。每次启动线程操作,都会先从主内存读取熟读到私有堆栈,然后已知只会对copy过来的变量进行读写,当线程结束的时候,就会将变量写回主内存。这里会出现线程安全问题,当线程A读取了主内存的变量V之后,线程B更改主内存的变量V的值,那么实际上线程A操作的变量V的值不是当前实际的值,如下图。

    volatile就是为了解决上述问题。当对使用volatile修饰的共享变量进行读写操作时,在编译成字节码命令时会多出Lock前缀指令,Lock指令的作用:

    1)引起处理器缓存写回主内存;

    2)如果其中一个处理器缓存写回到主内存,意味着会导致其他处理器的本地缓存失败;

    3)当处理器发现本地缓存失效,就会从主内存中重新读取该变量的数据。

    换句话说,每次对被volatile修饰的共享变量进行写操作是,都会更新该变量在主内存的值,同时强迫其他线程重新读取一次该线程的值到各自的本地缓存,如下图。

    volatile与sychronized的比较:

    1)volatile只能修饰变量,sychronized可以修饰变量、方法,以及代码块;

    2)多线程访问volatile修饰的变量时不会发生阻塞,而访问sychronized修饰的内容时,线程会发生阻塞;

    3)volatile只能保证可见性,而sychronized保证了原子性,间接保证了可见性,因为它会将本地缓存和主内存的数据同步。

  • 相关阅读:
    字符编码总结
    文件操作总结(2)
    Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) C. Five Dimensional Points 暴力
    UVA 10048
    UVA 247
    UVA 1151
    UVA 1395
    Codeforces Round #260 (Div. 1) D. Serega and Fun 分块
    Codeforces Beta Round #13 E. Holes 分块
    Codeforces Round #404 (Div. 2) E. Anton and Permutation 分块
  • 原文地址:https://www.cnblogs.com/SysoCjs/p/10326722.html
Copyright © 2011-2022 走看看