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

成熟交bgmbgmbgm在线/太极seo

成熟交bgmbgmbgm在线,太极seo,建设网站政策风险,文化传播做网站推广吗Java语言为了解决并发编程中存在的原子性、可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronized、volatile、final、concurren包等。本文,来分析一下另外一个关键字——volatile。 本文就围绕volatile展开,…

Java语言为了解决并发编程中存在的原子性、可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronized、volatile、final、concurren包等。本文,来分析一下另外一个关键字——volatile。

本文就围绕volatile展开,主要介绍volatile的用法、volatile的原理,以及volatile是如何提供可见性和有序性保障的等。

volatile这个关键字,不仅仅在Java语言中有,在很多语言中都有的,而且其用法和语义也都是不尽相同的。尤其在C语言、C++以及Java中,都有volatile关键字。都可以用来声明变量或者对象。下面简单来介绍一下Java语言中的volatile关键字。

volatile的用法


volatile通常被比喻成"轻量级的synchronized",也是Java并发编程中比较重要的一个关键字。和synchronized不同,volatile是一个变量修饰符,只能用来修饰变量。无法修饰方法及代码块等。

volatile的用法比较简单,只需要在声明一个可能被多线程同时访问的变量时,使用volatile修饰就可以了

public class Singleton {  private volatile static Singleton singleton;  private Singleton (){}  public static Singleton getSingleton() {  if (singleton == null) {  synchronized (Singleton.class) {  if (singleton == null) {  singleton = new Singleton();  }  }  }  return singleton;  }  
}  


如以上代码,是一个比较典型的使用双重锁校验的形式实现单例的,其中使用volatile关键字修饰可能被多个线程同时访问到的singleton。

volatile的原理


为了提高处理器的执行速度,在处理器和内存之间增加了多级缓存来提升。但是由于引入了多级缓存,就存在缓存数据不一致问题。

但是,对于volatile变量,当对volatile变量进行写操作的时候,JVM会向处理器发送一条lock前缀的指令,将这个缓存中的变量回写到系统主存中。

但是就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题,所以在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议

缓存一致性协议:每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读到处理器缓存里。

所以,如果一个变量被volatile所修饰的话,在每次数据变化之后,其值都会被强制刷入主存。而其他处理器的缓存由于遵守了缓存一致性协议,也会把这个变量的值从主存加载到自己的缓存中。这就保证了一个volatile在并发编程中,其值在多个缓存中是可见的

volatile与可见性


可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中是用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。所以,就可能出现线程1改了某个变量的值,但是线程2不可见的情况。

前面的关于volatile的原理中介绍过了,Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。

volatile与有序性


有序性即程序执行的顺序按照代码的先后顺序执行。

除了引入了时间片以外,由于处理器优化和指令重排等,CPU还可能对输入代码进行乱序执行,比如load->add->save 有可能被优化成load->save->add 。这就是可能存在有序性问题。

而volatile除了可以保证数据的可见性之外,还有一个强大的功能,那就是他可以禁止指令重排优化等。

普通的变量仅仅会保证在该方法的执行过程中所依赖的赋值结果的地方都能获得正确的结果,而不能保证变量的赋值操作的顺序与程序代码中的执行顺序一致。

volatile可以禁止指令重排,这就保证了代码的程序会严格按照代码的先后顺序执行。这就保证了有序性。被volatile修饰的变量的操作,会严格按照代码顺序执行,load->add->save 的执行顺序就是:load、add、save。

volatile与原子性


原子性是指一个操作是不可中断的,要全部执行完成,要不就都不执行。

线程是CPU调度的基本单位。CPU有时间片的概念,会根据不同的调度算法进行线程调度。当一个线程获得时间片之后开始执行,在时间片耗尽之后,就会失去CPU使用权。所以在多线程场景下,由于时间片在线程间轮换,就会发生原子性问题。

为了保证原子性,需要通过字节码指令monitorenter和monitorexit,但是volatile和这两个指令之间是没有任何关系的。

所以,volatile是不能保证原子性的。

在以下两个场景中可以使用volatile来代替synchronized:

1、运算结果并不依赖变量的当前值,或者能够确保只有单一的线程会修改变量的值。

2、变量不需要与其他状态变量共同参与不变约束。

除以上场景外,都需要使用其他方式来保证原子性,如synchronized或者concurrent包。

我们来看一下volatile和原子性的例子:

public class Test {public volatile int inc = 0;public void increase() {inc++;}public static void main(String[] args) {final Test test = new Test();for(int i=0;i<10;i++){new Thread(){public void run() {for(int j=0;j<1000;j++)test.increase();};}.start();}while(Thread.activeCount()>1)  //保证前面的线程都执行完Thread.yield();System.out.println(test.inc);}
}


以上代码比较简单,就是创建10个线程,然后分别执行1000次i++操作。正常情况下,程序的输出结果应该是10000,但是,多次执行的结果都小于10000。这其实就是volatile无法满足原子性的原因。

为什么会出现这种情况呢,那就是因为虽然volatile可以保证inc在多个线程之间的可见性。但是无法inc++的原子性。

总结与思考
我们介绍过了volatile关键字和synchronized关键字。现在我们知道,synchronized可以保证原子性、有序性和可见性。而volatile却只能保证有序性和可见性

http://www.lbrq.cn/news/1473247.html

相关文章:

  • 黄石商城网站建设/网络游戏推广公司
  • 网站插件代码大全/可以推广赚钱的软件
  • 制作免费制作个人网站怎么做/西地那非片能延时多久每次吃多少
  • 做便民工具网站怎么样/seo优化文章网站
  • 青岛建立网站电话/宣传渠道有哪些
  • wap社区游戏入口/网站优化的意义
  • 做企业云网站的企业邮箱/seo搜索优化专员招聘
  • 产品网站开发计划表/百度推广怎么操作流程
  • 网站建设是属于b2/google付费推广
  • 中山建设局网站首页/怎么在百度免费推广
  • 深圳网站制作开发/上海广告推广
  • 怎么做网站底部版权信息/企业qq邮箱
  • 给别人做的网站要复杂做安全扫描/营销推广48个方法
  • 有没有做软件的外包网站/滁州网站seo
  • 怎么做营销网站/怎么seo关键词优化排名
  • 建设商务网站的经济可行性分析/市场营销四大基本策略
  • 制作网站网站/广州推广seo
  • 天津企业网站策划公司/适合网络营销的产品
  • 类似建E网模型网站建设/湖南网站seo推广
  • 哪家网站做推广好/百度获客平台
  • 自助下单网站怎么做/女教师遭网课入侵直播
  • 企业门户网站开发要多少钱/东莞优化排名公司
  • 专业做简历的网站/seo网站系统
  • 宜昌市住房和城乡建设官方网站/微信小程序开发教程
  • 建设网站有哪些/优化推广网站排名
  • 南通网站建设推广专家/网站建设推广公司
  • 个人网站起个名字/厦门站长优化工具
  • 网站建设的前期准备/谷歌浏览器下载安卓版
  • 腹黑的网站骚动做图动态网站/网络营销师官网
  • 常见的网站开发工具有哪些/百度怎么找人工客服
  • elk部署加日志收集
  • systmctl的作用,使用场景和用法
  • diffusion原理和代码延伸笔记1——扩散桥,GOUB,UniDB
  • ECMAScript2024(ES15)新特性
  • 用Python+MySQL实战解锁企业财务数据分析
  • 智能Agent场景实战指南 Day 26:Agent评估与性能优化