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

公司网站如何宣传推广桂林红豆网论坛

公司网站如何宣传推广,桂林红豆网论坛,专业制作网站公司哪家好,关于棋牌游戏网站建设文案VolatileVolatile关键字用于确保共享数据的可见性与有序性#xff0c;但是并不能保证方法的原子性#xff0c;在程序中对Volatile关键字使用得当的话#xff0c;它比synchronized的使用和执行成本会更低#xff0c;因为他不会引起线程的上下文切换和调度。先讲一下重排序但是并不能保证方法的原子性在程序中对Volatile关键字使用得当的话它比synchronized的使用和执行成本会更低因为他不会引起线程的上下文切换和调度。先讲一下重排序重排序是什么?我们所编写的程序会经过编译器编译然后写入内存中。在执行时CPU会从内存中读取并执行在这里编译器与CPU为了提高程序执行时的效率会对代码的执行顺序进行优化但代码输出的结果并不会改变所以从宏观上我们认为程序是按照我们的思路来运行的这里有三种重排序1.编译器重排序在不改变代码语义的情况下对重新对代码执行顺序进行排序。2.CPU重排序我们的代码在CPU处理时会被编译成各种指令若不存在数据依赖性处理器在执行代码语句时可以对其生成的指令进行重排序。3.缓存的重排序在CPU对缓存进行读/写时加载与存储的操作是存在乱序的。所以在单线程运行情况下的重排序是提升程序的执行效率这些重排序对程序运行是无害的而在多线程运行情况下线程交替执行则会出问题。先看一个比较常见的例子class Counter{public static int count 0;public static boolean flag false;public void inc(){ count; //-------操作1 flag true; //-------操作2}public int getCount(){ if(falg){ flag false; //-------操作3 return count; //-------操作4 } return 0;}正常情况下是调用inc()后执行操作1与操作2然后再调用getCount()执行操作3与操作4但是再多线程情况下如果对这段代码进行了重排序很有可能会出现如下结果1.线程A调用了inc()代码被重排序后执行顺序为先将flag置为ture再对count进行自增。2.而此时线程B调用了getCount()此时线程A只运行了flag置为ture还没有执行到对count自增这时线程B就会返回非预期值。在我们使用Volatile关键字时JMM会向CPU指令中插入特定的指令来确保共享数据可见性与有序性。1.内存屏障用于保障有序性内存屏障是一组同步指令集使得CPU与编译器在对加入内存屏障之前的所有读写操作都执行后才可以开始执行此点之后的操作。它用于保障程序的有序执行被插入内存屏障指令的代码会对其实际代码执行顺序进行限制有以下四种内存屏障根据JSR-133 CookBook中的描述我们可以从下表中得出结论1.如果第二个操作是Volatile写那么无论第一个操作是什么类型的操作都不能改变代码的执行顺序。它用于保障Volatile写之前的操作不会被重排序到其后执行。2.如果第一个操作是Volatile读那么无论第二个操作是什么类型的操作都不能改变代码的执行顺序。它用于保障Volatile读之后的操作不会被冲排序到其前面执行。为了达到上述规则编译器在生成字节码时会在指令中插入内存屏障来保证Volatile数据前后代码的执行顺序。读1.在对一个Volatile读操作之后添加一个LoadLoad指令。(用来确保当前读操作之后的读操作都不会被重排序)2.对于一个Volatile读操作之后添加一个LoadStore指令。(用来确保当前读操作于后续写操作之前进行)写1.在对一个Volatile写操作之前添加一个StoreStore指令。(用来确保当前写操作之前的写操作不会被重排序到其后面执行)2.在一个Volatile写操作之后添加一个StoreLoad指令。(用来确保当前写操作于之后读操作之前执行)2.可见性当共享变量被Volatile关键字修饰后对Volatile变量进行读写都使JVM在变量前插入LOCK前缀指令若不涉及缓存一致性协议LOCK前缀指令会锁住总线使其他CPU暂时无法通过总线访问内存作用如下:1.对被Volatile关键字修饰的变量进行写操作Lock指令会直接将工作内存中的变量刷新至主存中。1.对于被Volatile关键字修饰的变量进行读操作Lock指令会令工作内存中的该变量失效直接从主存中读取。这里需要注意的是Volatile关键字只能修饰单个变量它无法保障代码块的原子性如a这样的操作并不能保障它的原子性因为它是由做个指令集组成。volitatile的使用情景1.状态标记2.double checksynchronizedsynchronized关键字用于解决在并发编程时的有序性、原子性、可见性。相比于Volatile关键字synchronized锁能够控制的范围更大使用synchronized关键字修饰方法或代码块时能够确保在同一时刻最多只有一个线程能够执行该代码。当synchronized修饰方法时它锁住的是对象的实例synchronized(this)当作用在对象实例时它锁住的是代码块。synchronized实现原理我们对于synchronized的理解也许只在于其互斥的特性认为线程在执行加上synchronized关键字的代码需要执行该代码块或方法的线程就会竞争该代码块或方法的互斥锁。若竞争成功则线程该代码块的执行权而未竞争到该锁的线程只能被阻塞等到持有锁的线程执行代码块或方法执行完毕后释放锁其他线程才能继续竞争而这仅仅synchronized关键字中重量锁的特性。其实synchronized在经过不断优化后其锁的特性为偏向锁-》轻量锁-》重量锁三种偏量锁和轻量锁在某种意义上能够减少重量锁带来的开销但是他们都不能替代重量锁下面就让我们来看看这三种锁的原理。重量锁重量锁故名思议就是需要消耗大量系统资源的锁因为很重嘛。当多线程执行到具有synchronized关键字的代码时会进行锁竞争竞争失败的线程会进入一个阻塞队列而获得锁的线程会获取代码的执行权。而synchronized锁是一种非公平锁当线程竞争失败时会阻塞我们知道线程从运行状态切换到阻塞状态是依赖于操作系统从用户态切换到内核态来执行的这种切换会消耗大量的系统资源(因为用户态与内核态都有各自专用的内存空间专用的寄存器租等用户态切换至内核态需要传递给许多变量、参数给内核内核也需要保护好用户态在切换时的一些寄存器值、变量等以便内核态调用结束后切换回用户态继续工作)。如果该方法是一个高频操作时这将会消耗很多CPU处理时间。所以为了避免线程阻塞带来的消耗引入了轻量锁。轻量锁轻量锁是为了避免在没有竞争的情况下重量锁所带来的开销一旦该对象有多个线程竞争轻量锁就会升级为重量锁所以轻量锁和偏向锁并不能在多线程竞争情况下代替重量锁!!!只能在无锁竞争的条件下减缓重量锁的开销。在了解轻量锁前我们先了解一下CAS操作与mark word标记他们是实现轻量锁的基础。CASCAS英文名(compare and swap)也就是比较交换java语言在代码层面对其进行了封装实际上是它是通过调用jni来实现的它本质上是调用了cpu的指令集。在JUC中大量的使用到了CAS操作它作为一种乐观锁使用它就能实现所谓的无锁交换。在CAS操作中一个变量有三个状态值一个是内存值V一个是旧的预期值A还有一个是要替换新值的B。对应到JMM中V表示为主存中的值而旧的预期值A为我们工作内存中的值而B为操作后的新值若V与B相等就说明该变量没有被其他线程修改那么将变量替换为B值不相等则不进行交换。所以使用CAS操作的开销相对于线程竞争过程中的阻塞唤醒引起的上下文切换来说小了很多(竞争情况下操作队列线程挂起上下文切换)。MARK WORD我们知道java的Class文件是对java程序二进制文件格式的定义java编译器将Class文件编译成字节码在jvm中运行在堆内存中的对象都含有各自的对象头用于确定obj在运行时的状态而Mark Word正是一个长为32bit的对象头是用来标记同步线程的这里先解释HashCode 与state两个变量的值轻量锁与重量锁在HashCode中存入的值为指向占有锁的线程的栈中的存储该线程所占有锁的信息的地址(有点绕口其实就是存了一个地址下面会详细说)state表示当前对象所处的状态下面我们来看一下轻量锁如何来实现锁机制这里分两种情况。该对象没有被其他线程锁定因为轻量锁是由偏向锁升级而来通过判断tag是否为1与锁标志位是否为01来得知对象是否有没有被其他线程占用若没有被其他线程占用jvm会在当前线程的栈中创建一个lock record空间将当前需要被锁定的对象的mark word的拷贝副本存入到lock record中然后尝试使用CAS操作将mark Word中的betifields字段中的值更新为指向lock record空间的地址若CAS操作成功则将state更新为00表示轻量锁添加成功当前线程拥有对该对象的执行权。2.出现锁竞争或对象已经被其他线程占用若有两个线程同时对未被锁定的对象上轻量锁时会有一个线程竞争失败此时竞争失败标志是CAS操作失败则该线程会自旋一段时间若还是CAS操作失败则该轻量锁会升级为重量锁竞争失败的线程进入阻塞状态state标志置为10且mark down中重量锁指针会被修改。当占有该轻量锁的线程释放锁时竞争失败的锁会被唤醒重新竞争锁。2.unlock解锁过程也是将lock record中存储的mark down副本与object头中mark down进行CAS操作若两者相等则说明没有其他线程竞争该轻量锁释放成功。如果失败则当前轻量锁存在竞争则锁会升级为重量锁。从上述轻量锁实现过程我们可以看到轻量锁是使用CAS操作来代替重量锁的互斥操作在语言层面上实现了同步操作这样能够节约许多系统开销但是需要注意的是这都是在无锁竞争的前提条件下因为轻量锁并不能代替重量锁。偏向锁偏向锁是在JVM1.6中引入了主要也是为了解决在没有竞争情况下锁性能的问题通过上述轻量锁的讲解我们了解到轻量锁是通过CAS操作来避免重量锁的阻塞开销。但是我们知道CAS操作也是需要通过本地调用来实现归根到底还是通过CPU指令集的实现JVM只是封装了该指令调用。所以CAS操作会产生一定的副作用。因为CPU通过总线来实现对内存中数据的读写而多核CPU在将自身cache内存中的数据刷新至主存中时会引触发“缓存一致性协议”就是说CPU1对主存中的值进行了改变“缓存一致性协议”会通知CPU2、CPU3自身cache中该值已经失效需要重新读取。若在轻量锁中每次进入操作若CAS操作很频繁的话会给总线带来巨大的开销而偏向锁就是为了避免这个开销产生的。若线程在没有竞争的情况下去获取某一对象的锁会通过CAS操作将自身的Thread ID 存入Mark Word中如果CAS操作成功则表示该线程拥有该对象的执行权而偏向锁是具有可重入性的偏向吗就是偏袒第一次占有该对象锁的线程当该线程再次竞争该对象的锁时只需要对比较Mark Word中的Thread ID 与自身的Thread ID 是否相同,相同则表明没有其他线程竞争可以继续使用;如果这时有线程来竞争则该线程在执行完代码块后偏向锁会升级为轻量锁。这里需要注意的是偏向锁只有再有竞争时才会撤销若没有竞争则一直是第一次获得偏向锁的线程持有。我们可以看到偏向锁的出现更加降低了线程初次获取锁的开销。
http://www.yutouwan.com/news/88911/

相关文章:

  • 一个网站的建设步骤官网网站模板
  • 网站测速工具怎样推广app别人才愿意下载
  • 成品网站怎样建设建网站定制
  • 网站广告位代码凡客诚品网址是多少
  • 本地主机 搭建网站百度2345网址导航
  • 中国人做暧暧视频网站绿园区建设局网站
  • a做爰视频免费观费网站在线视频网站 一级做爰片
  • 山东天成水利建设 网站怎么注册一个软件平台
  • 泉州建站方案宿迁房产中介
  • 公司网站建设方案pptru域名注册
  • 网站建设的好公司网上营销策略有哪些
  • 班级网站建设模板北京网站建设市场
  • 自己做电台直播的网站制作企业网站页面多少钱
  • 毕设网站开发需要做什么摄影网站功能设计
  • 网站 模板下载网易云跟帖 wordpress
  • 推荐几个做网站比较好的公司wordpress数据库容量
  • 腾讯理财是什么样的做网站建立公司网站时什么是重要的
  • 免费舆情网站直接打开app开发工具哪个好
  • 网站建设步骤详解视频教程个人网站搭建平台
  • 菏泽网站建设 梧桐树下载应用市场
  • html 网站新功能介绍滕州网站设计
  • 怎么注册网站域名个人简历表格电子版下载
  • 江苏分销网站建设网站建设的目的及功能
  • 河南做网站最好的公司药品网站前置审批
  • 用WordPress做网站入门课电子商务网站的建站流程
  • 做网站app 需要多少钱塑业东莞网站建设
  • 做情书直接点网站自己做网站模板
  • 网站建设登录结构图国外做化工网站
  • wordpress 地址插件昆明网站seo优化
  • 山西网站制作公司东莞市做网站的最好的是哪家的