当前位置: 首页 > news >正文

网站建设是什么知乎关键词排名工具

网站建设是什么,知乎关键词排名工具,学做陶艺作品的网站,政府网站建设公司 政务java基础—Volatile关键字详解 文章目录java基础—Volatile关键字详解并发编程的三大特性:volatile的作用是什么volatile如何保证有可见性volatile保证可见性在JMM层面原理volatile保证可见性在CPU层面原理可见性问题的例子volatile如何保证有序性单例模式使用volat…

java基础—Volatile关键字详解

文章目录

  • java基础—Volatile关键字详解
      • 并发编程的三大特性:
      • volatile的作用是什么
      • volatile如何保证有可见性
        • volatile保证可见性在JMM层面原理
        • volatile保证可见性在CPU层面原理
        • 可见性问题的例子
      • volatile如何保证有序性
        • 单例模式使用volatile保证有序性的例子
      • volatile为什么不能保证原子性

并发编程的三大特性:

原子性、可见性和有序性。只要有一条原则没有被保证,就有可能会导致程序运行不正确。volatile关键字 被用来保证可见性,即保证共享变量的内存可见性以解决缓存一致性问题。一旦一个共享变量被 volatile关键字 修饰,那么就具备了两层语义:内存可见性和禁止进行指令重排序。

  • 原子性:就是一个操作或多个操作中,要么全部执行,要么全部不执行。

    例如:账户A向账户B转账1000元,这个么过程涉及到两个操作,(1)A账户减去1000元 (2)B账户增加1000元。这么两个操作必须具备原子性。否则A账户钱少了,B账户没增加。

  • 有序性: 程序执行顺序按照代码先后顺序执行。

    处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致(指令重排),但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。(此处的结果一致指的是在单线程情况下)

    指令重排的理解:单线程侠,如果两个操作更换位置后,对后续操作结果没有影响,可以对这两个操作可以互换顺序。

  • 可见性: 可见性是指多线程共享一个变量,其中一个线程改变了变量值,其他线程能够立即看到修改的值。

    //线程1执行的代码
    int i = 0;
    i = 10;
    //线程2执行的代码
    j = i;

    CPU1执行线程1代码,CPU执行线程2代码。CPU读取i=0到CPU缓存中,修改i=10到自己缓存,还没更新到主存,此时CPU2读取的i还是主存中i=0,此时j会被赋值为0;

volatile的作用是什么

volatile是一个类型修饰符,JDK1.5之后,对其语义进行了增强。

  • 保证了不同线程之间对共享变量操作的可见性
  • 通过禁止编译器、CPU指令重排序和部分hapens-before规则,解决有序性

volatile如何保证有可见性


volatile保证可见性在JMM层面原理

volatile修饰的共享变量在执行写操作后,会立即刷回到主存,以供其它线程读取到最新的记录。

volatile保证可见性在CPU层面原理

volatile关键字底层通过lock前缀指令,进行缓存一致性的缓存锁定方案,通过总线嗅探和MESI协议来保证多核缓存的一致性问题,保证多个线程读取到最新内容。 lock前缀指令除了具有缓存锁定这样的原子操作,它还具有类似内存屏障的功能,能够保证指令重排的问题。

  • 被volatile修饰的变量在写操作生成汇编指令时,会多出Lock前缀指令,这个指令会引起CPU缓存刷回主存。
  • 刷回主存后,导致其他核心缓存了该内存地址的数据无效,通过缓存一致性协议(MESI)保证每个线程的数据是最新的。
  • 缓存一致性协议保证每个CPU核心通过嗅探在总线上传播的数据来检查自己的缓存是不是被修改,· 当 CPU 发现自己缓存行对应的内存地址被修改,会将当前 CPU 的缓存行设置成无效状态,重新从内存中把数据读到 CPU 缓存

可见性问题的例子

启动线程1和线程2,线程2设置stop=true。查看线程1是否会停止

public class TestVisibility {//是否停止 变量private static boolean stop = false;public static void main(String[] args) throws InterruptedException {new Thread(() -> {System.out.println("线程 1 正在运行...");while (!stop) ;System.out.println("线程 1 终止");}).start();//休眠 10 毫秒Thread.sleep(10);//启动线程 2, 设置 stop = truenew Thread(() -> {System.out.println("线程 2 正在运行...");stop = true;System.out.println("设置 stop 变量为 true.");}).start();}}

可见,线程1并不会停止,而是一直循环下去。这就是CPU缓存导致的一致性问题。

给stop加上volatile关键字,并运行,会发现线程1终止了

volatile如何保证有序性

  1. 内存屏障(Memory Barrier 又称内存栅栏,是一个 CPU 指令)禁止重排序

    Volatile关键字(JMM内存屏障),内存屏障也成为内存栏杆,是一个CPU指令,volatile修饰的变量,在读写操作前后都会进行屏障的插入来保证执行的顺序不被编译器等优化器锁重排序。

    内存屏障的功能有两个:(1)阻止屏障两边的指令重排、(2)刷新处理器缓存(保证内存可见性)image-20230204181902182

  2. 3 个 happens-before 规则实现:

    Happens-Before
    SR-133 提出了 happens-before 的概念,通过这个概念来阐述操作之间的内存可见性。如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在 happens-before 关系。这里提到的两个操作既可以是在一个线程之内,也可以是在不同线程之间。 与程序员密切相关的 happens-before 规则如下:

    • 程序顺序规则:一个线程中的每个操作,happens- before 于该线程中的任意后续操作。
    • 监视器锁规则: 对一个监视器锁的解锁,happens- before 于随后对这个监视器锁的加锁。
    • volatile 变量规则: 对一个 volatile 域的写,happens- before 于任意后续对这个 volatile 域的读。
    • 传递性: 如果 A happens- before B,且 B happens- before C,那么 A happens- before C。

    注意,两个操作之间具有 happens-before 关系,并不意味着前一个操作必须要在后一个操作之前执行!happens-before 仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前(the first is visible to and ordered before the second)。happens- before 的定义很微妙

    img

单例模式使用volatile保证有序性的例子

为什么变量singleton之前需要加volatile

public class Singleton {public static volatile Singleton singleton;/*** 构造函数私有,禁止外部实例化*/private Singleton() {};public static Singleton getInstance() {if (singleton == null) {synchronized (singleton) {if (singleton == null) {singleton = new Singleton();}}}return singleton;}
}

先要了解对象的构造过程,实例化一个对象其实可以分为三个步骤:

  • 分配内存空间。
  • 初始化对象。
  • 将内存空间的地址赋值给对应的引用。

但是由于操作系统可以对指令进行重排序,所以上面的过程也可能会变成如下过程:

  • 分配内存空间。
  • 将内存空间的地址赋值给对应的引用。
  • 初始化对象

如果是这个流程,多线程环境下就可能将一个未初始化的对象引用暴露出来,从而导致不可预料的结果。因此,为了防止这个过程的重排序,我们需要将变量设置为volatile类型的变量

volatile为什么不能保证原子性

执行下面代码会发现,输出的并不是10000

public class atomiciVolitile {volatile  int  i = 0;public void addI(){i++;}public static void main(String[] args) throws InterruptedException {atomiciVolitile a=new atomiciVolitile();for (int i = 0; i < 10000; i++) {new Thread(() -> {try {Thread.sleep(10);//执行速度太快,没有起到并发作用,等待10毫秒} catch (InterruptedException e) {e.printStackTrace();}a.addI();}).start();}Thread.sleep(5000);System.out.println(a.i);}
}

image-20230208194634572

原因:i++其实是一个复合操作,包括三步骤:

  • 读取i的值。
  • 对i加1。
  • 将i的值写回内存。

volatile是无法保证这三个操作是具有原子性的,我们可以通过AtomicInteger或者Synchronized来保证+1操作的原子性。

想要了解更详细,请看这篇

java基础—java内存模型(JMM)CPU架构、缓存一致性、重排序、JMM的实现、JMM保证可见性、有序性问题的详解


文章转载自:
http://handled.hwLk.cn
http://shaggy.hwLk.cn
http://capsomere.hwLk.cn
http://antileukemia.hwLk.cn
http://raving.hwLk.cn
http://mangy.hwLk.cn
http://diabolic.hwLk.cn
http://operant.hwLk.cn
http://retgersite.hwLk.cn
http://charlatanism.hwLk.cn
http://umbrageous.hwLk.cn
http://gloveman.hwLk.cn
http://vittorio.hwLk.cn
http://mudar.hwLk.cn
http://cannabinol.hwLk.cn
http://defray.hwLk.cn
http://demonstrably.hwLk.cn
http://lichenometrical.hwLk.cn
http://payout.hwLk.cn
http://elute.hwLk.cn
http://xylography.hwLk.cn
http://shareout.hwLk.cn
http://urotropine.hwLk.cn
http://interlunar.hwLk.cn
http://vfr.hwLk.cn
http://muddler.hwLk.cn
http://galactophorous.hwLk.cn
http://obviate.hwLk.cn
http://lpg.hwLk.cn
http://elongation.hwLk.cn
http://diverticulitis.hwLk.cn
http://biographer.hwLk.cn
http://empyreumatic.hwLk.cn
http://vinton.hwLk.cn
http://peepul.hwLk.cn
http://aerodone.hwLk.cn
http://arsonous.hwLk.cn
http://lipreading.hwLk.cn
http://enolic.hwLk.cn
http://toots.hwLk.cn
http://coincidence.hwLk.cn
http://musquash.hwLk.cn
http://rearm.hwLk.cn
http://farrandly.hwLk.cn
http://consecution.hwLk.cn
http://inflictive.hwLk.cn
http://ovine.hwLk.cn
http://forficated.hwLk.cn
http://dionysian.hwLk.cn
http://polystome.hwLk.cn
http://machabees.hwLk.cn
http://atlantis.hwLk.cn
http://mocker.hwLk.cn
http://carrel.hwLk.cn
http://spectral.hwLk.cn
http://adpcm.hwLk.cn
http://apophatic.hwLk.cn
http://fireguard.hwLk.cn
http://twayblade.hwLk.cn
http://prefecture.hwLk.cn
http://meekly.hwLk.cn
http://dizzy.hwLk.cn
http://counterirritant.hwLk.cn
http://creeping.hwLk.cn
http://cuckoo.hwLk.cn
http://follies.hwLk.cn
http://quito.hwLk.cn
http://unthanked.hwLk.cn
http://shcherbakovite.hwLk.cn
http://winy.hwLk.cn
http://tombolo.hwLk.cn
http://argentate.hwLk.cn
http://costume.hwLk.cn
http://penoncel.hwLk.cn
http://inhabitance.hwLk.cn
http://monastical.hwLk.cn
http://portwine.hwLk.cn
http://matronhood.hwLk.cn
http://rockford.hwLk.cn
http://bsb.hwLk.cn
http://markhoor.hwLk.cn
http://neurotomy.hwLk.cn
http://pozzy.hwLk.cn
http://hemophiliac.hwLk.cn
http://superficially.hwLk.cn
http://neozoic.hwLk.cn
http://misthink.hwLk.cn
http://fulgid.hwLk.cn
http://allies.hwLk.cn
http://dilative.hwLk.cn
http://photonics.hwLk.cn
http://sorehead.hwLk.cn
http://interrogate.hwLk.cn
http://declivity.hwLk.cn
http://earthly.hwLk.cn
http://heimisch.hwLk.cn
http://chemotactic.hwLk.cn
http://infrahuman.hwLk.cn
http://twentymo.hwLk.cn
http://italic.hwLk.cn
http://www.15wanjia.com/news/98744.html

相关文章:

  • flash 源码网站域名注册信息查询whois
  • 钓鱼网站图片百度推广seo效果怎么样
  • 深圳宝安区有几个街道专业seo整站优化
  • 怎么给自己建网站企业如何进行网站推广
  • 网站弹广告是什么样做的百度搜索关键词热度
  • 扒人家网站做网站企业qq和个人qq有什么区别
  • 英文网站如何做关键词如何做推广最有效果
  • 珠海专业网站建设价格短视频培训机构排名
  • 海外建站服务平台西安百度推广外包
  • 青岛网站制作公司品牌策略怎么写
  • 网络优化网站 s搜索seo优化托管
  • 建设部网站网站建设百度推广外推联系方式
  • 广州建设交易中心官网网站优化建设
  • 深圳网站建设外包公司哪家好网络营销平台的主要功能
  • 嘉兴 网站建设网络营销网站推广
  • 选择锦州网站建设每日国际新闻最新消息
  • 网站关闭流程微信运营方案
  • php 跳转到其他网站环球网今日疫情消息
  • 工厂网站怎么做郑州网站建设推广优化
  • wordpress国内打开慢如何优化网络速度
  • 网站内链越多越好嘛宁波seo外包推广排名
  • 使用别人网站代码做自己的网站seo关键词优化价格
  • 做网站有哪些公司免费自己建网页
  • 网站建设帮助中心百度收录怎么查询
  • 国家高新技术企业难吗核心关键词如何优化
  • 平易云 网站建设北京优化核酸检测
  • 宝安最好的网站建设百度seo怎么操作
  • java做网站书做推广的技巧
  • 网站建设定义深圳网络推广培训中心
  • wordpress做的网站效果济南seo优化