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

网站对网络营销的作用机械网站模板

网站对网络营销的作用,机械网站模板,上海公司排名,wordpress 正在跳转中 请稍等volatile 关键字 volatile 能保证内存可见性 volatile 修饰的变量, 能够保证 “内存可见性” 示例代码: 运行结果: 当输入1(1是非O)的时候,但是t1这个线程并沿有结束循环, 同时可以看到,t2这个线程已经执行完了,而t1线程还在继续循环. 这个情况,就叫做内存可见性问题 ~~ 这… volatile 关键字 volatile 能保证内存可见性 volatile 修饰的变量, 能够保证 “内存可见性” 示例代码: 运行结果: 当输入1(1是非O)的时候,但是t1这个线程并沿有结束循环, 同时可以看到,t2这个线程已经执行完了,而t1线程还在继续循环. 这个情况,就叫做内存可见性问题 ~~ 这也是一个线程不安全问题(一个线程读,一个线程改) while (myCounter.flag 0) { // 循环体空着,什么也不做 } 这里使用汇编来理解,大概就是两步操作: load, 把内存中 flag 的值,读取到寄存器里.cmp, 把寄存器的值,和0进行比较,根据比较结果,决定下一步往哪个地方执行(条件跳转指令). 上述是个循环,这个循环执行速度极快,一秒钟执行百万次以上… 循环执行这么多次,在线程 t2 真正修改之前, load得到的结果都是一样的; 另一方面, load操作和cmp操作相比,速度慢非常非常多!!! 注: CPU针对寄存器的操作,要比内存操作快很多,快3-4数量级; 计算机对于内存的操作,比硬盘快3-4个数量级. 由于 load 执行速度太慢(相比于cmp来说),再加上反复 load 到的结果都一样, JVM 就做出了一个非常大胆的决定 ~~ 判定好像没人改 flag 值,不再真正的重复 load 了,干脆就只读取一次就好了 编译器优化的一种方式. 实际上是有人在修改的,但是 JVM/编译器 对于这种多线程的情况,判定可能存在误差. 此时,就需要我们手动干预了,可以给 flag 这个变量加上 volatile 关键字,意思就是告诉编译器,这个变量是易变的,要每次都重新读取这个变量的内存内容,不能再进行激进的优化了. 博主感慨: 快和准之间往往不可兼得 内存可见性问题 一个线程针对一个变量进行读取操作,同时另一个线程针对这个变量进行修改,此时读到的值,不一定是修改之后的值;这个读线程没有感知到变量的变化; 归根结底是 编译器/JVM 在多线程环境下优化时产生了误判了. 备注: (1)上述说的内存可见性编译器优化的问题,也不是始终会出现的(编译器可能存在误判,也不是100%就误判!); (2)编译器的优化,很多时候是“玄学问题”,应用程序这个角度是无法感知的.编译器的优化,很多时候是“玄学问题”,应用程序这个角度是无法感知的. 代码改正: class MyCounter {volatile public int flag 0; }运行结果: 注意事项: (1) volatile 只能修饰变量; (2) volatile 不能修饰方法的局部变量,局部变量只能在你当前线程里面用,不能多线程之间同时读取/修改(天然就规避了线程安全问题); (1)局部变量只能在当前方法里使用的,出了方法变量就没了,方法内部的变量在栈”这样的内存空间上; (2)每个线程都有自己的栈空间,即使是同一个方法,在多个线程中被调用,这里的局部变量也会处在不同的栈空间中,本质上是不同变量,也就涉及不到修改/读取同一个变量的操作; (3)栈记录了方法之间的调用关系; 个人理解: 局部变量只对当前线程可见,其他线程看不了. (3) 如果一个变量在两个线程中,一个读,一个写,就需要考虑volatile 了; (4) volatile 不保证原子性,原子性是靠 synchronized 来保证的. synchronized 和 volatile 都能保证线程安全 不能使用 volatile 处理两个线程并发这样的问题; (5) 如果涉及到某个代码,既需要考虑原子性,有需要考虑内存可见性,就把 synchronized 和 volatile 都用上就行了. 从 JMM 的角度重新表述内存可见性问题 内存可见性问题,其他的一些资料,谈到了JMM(Java Memory Mode ~~ Java内存模型) 从 JMM 的角度重新表述内存可见性问题(Java的官方文档的大概表述): Java 程序里,主内存,每个线程还有自己的工作内存(线程 t1 的和线程 t2 的工作内存不是同一个东西); 线程 t1 进行读取的时候,只是读取了工作内存的值; 线程 t2进行修改的时候,先修改的工作内存的值,然后再把工作内存的内容同步到主内存中,但是由于编译器优化,导致线程 t1没有重新的从主内存同步数据到工作内存,读到的结果就是“修改之前的结果. 如果把主内存”代替成内存,把“工作内存代替成CPU寄存器,就容易理解. 注: 之所以上面这段话这么晦涩,是翻译不行,翻译官得背锅 ~~ 翻译的结果让人误会了!!! 主内存: main memory 主存,也就是平时所说的内存 工作内存: work memory 工作存储区,并非是所说的内存,而是CPU上存储数据的单元(寄存器) 为什么Java这里,不直接叫做“CPU寄存器,而是专门搞了工作内存”说法呢? 这里的工作内存,不一定只是CPU的寄存器,还可能包括CPU的缓存cache. 当CPU要读取一个内存数据的时候,可能是直接读内存也可能是读cache还能是读寄存器… 引入cache之后,硬件结构就更复杂了,工作内存(工作存储区): CPU寄存器 CPU的cache; 一方面是为了表述简单,另一方面也是为了避免涉及到硬件的细节和差异,Java里就使用工作内存这个词来统称(泛指)了;毕竟,现实中有的 CPU 可能没有 cache, 有的 CPU 有;有的 CPU 可能有一个cache,还可能有多个;现代的 CPU 普遍是3级cache, L1, L2, L3,总之,情况多样. 注: 学校的计算机系统结构”会讲解CPU内部的结构,尤其是寄存器, cache,指令等等,上这门课的时候要好好听讲. wait 和 notify 线程最大的问题,是抢占式执行,随机调度~~ 程序猿写代码,不喜欢随机,喜欢确定的东西,于是发明了一些办法,来控制线程之间的执行顺序,虽然线程在内核里的调度是随机的,但是可以通过一些 API 让线程主动塞,主动放弃CPU(给别的线程让路). 比如,t1,t2 两个线程,希望t1先干活,干的差不多了,再让t2来干.就可以让t2先wait(阻塞,主动放弃CPU)等t1干的差不多了,再通过notify 通知t2,把t2唤醒,让t2接着干. 那么上述场景,使用 join 或者 sleep行不行呢? 使用join,则必须要t1彻底执行完,t2才能运行.如果是希望t1先干50%的活,就让t2开始行动,join无能为力. 使用sleep,指定一个休眠时间的,但是t1执行的这些活,到底花了多少时间,不好估计. 使用wait和notify可以更好的解决上述的问题. 注: wait, notify, notifyAll 这几个类,都是Object类(Java里所有类的祖宗)的方法.Java里随便new个对象,都可以有这三个方法!! wait wait 进行阻塞.某个线程调用wait方法,就会进入阻塞(无论是通过哪个对象 wait的),此时就处在WAITING状态. wait 不加任何参数,就是一个死等一直等待,直到有其它线程唤醒它. 示例代码: public class ThreadDemo16 {public static void main(String[] args) throws InterruptedException {Object object new Object();object.wait();} }throws InterruptedException : 这个异常,很多带有阻塞功能的方法都带.这些方法都是可以 interrupt 方法通过这个异常给唤醒的. 运行结果: IllegalMonitorStateException ~~ 非法的锁状态异常 ~~ 锁的状态,无非就是被加锁的状态和和被解锁的状态 为什么有这个异常,要先理解 wait 的操作是干什么了. 1.先释放锁 2.进行阻塞等待 3.收到通知之后,重新尝试获取锁,并且在获取锁后,继续往下执行. 这里锁状态异常,就是没加锁呢,就想着释放锁.就好比单身着呢,就想着分手. public static void main(String[] args) throws InterruptedException {Object object new Object();synchronized (object) {System.out.println(wait 之前);object.wait();System.out.println(wait 之后);}}虽然这里wait是阻塞了,阻塞在 synchronized 代码块里,实际上,这里的阻塞是释放了锁的,此时其他线程是可以获取到object这个对象的锁的,此时这里的阻塞,就处在WAITING状态. t1.start(); t2.start();如果代码这里写作 t1.start 和 t2.start 由于线程调度的不确定性,此时不能保证一定是先执行 wait 后执行notify. 如果调用notify,此时没有线程wait,此处的wait是无法被唤醒的!!!(这种通知就是无效通知). 因此此处的代码还是要尽量保证先执行wait后执行notify才是有意义的. 改正的代码: public static void main(String[] args) throws InterruptedException {Object object new Object();Thread t1 new Thread(() - {// 这个线程负责进行等待System.out.println(t1: wait 之前);try {synchronized (object) {object.wait();}} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(t2: wait 之后);});Thread t2 new Thread(() - {System.out.println(t2: notify 之前);synchronized (object) {// notify 务必要获取到锁,才能进行通知object.notify();}System.out.println(t2: notify 之后);});t1.start();// 此处写的 sleep 500 是大概率会让 t1 先执行 wait 的// 极端情况下,电脑特别卡的时候, 可能线程的调度时间就超过了 500 ms// 还是可能 t2 先执行 notifyThread.sleep(500);t2.start();}运行结果: 此处,先执行了wait,很明显wait操作阻塞了,没有看到wait之后的打印; 接下来执行到了t2, t2进行了notify的时候,才会把t1的wait唤醒.t1才能继续执行. 只要t2不进行notify,此时t1就会始终wait下去(死等). wait无参数版本,就是死等的. wait带参数版本,指定了等待的最大时间. wait的带有等待时间的版本,看起来就和sleep有点像.其实还是有本质差别的: 虽然都是能指定等待时间,也都能被提前唤醒(wait是使用notify 唤醒, sleep使用interrupt唤醒)但是这里表示的含义截然不同. notify唤醒wait,这是不会有任何异常的.(正常的业务逻辑),interrupt唤醒sleep 则是出异常了(表示一个出问题了的逻辑). 如果当前有多个线程在等待object对象,此时有一个线程 object.notify(),此时是随机唤醒一个等待的线程.(不知道具体是哪个),但是,可以用多组不同的对象来控制线程的执行顺序. 比如,有三个线程,希望先执行线程1,再执行线程2,再执行线程3, 创建obj1,供线程1,2使用创建obj2,供线程2,3使用线程3, obj2.wait 线程2.obj1.wait(),唤醒之后执行obj2.notify() 线程1执行自己的任务,执行完了之后,obj1.notify即可. notifyAll和notify非常相似. 多个线程 wait 的时候, notify随机唤醒一个, notifyAll 所有线程都唤醒,这些线程再一起竞争锁…
http://www.huolong8.cn/news/162015/

相关文章:

  • 免费影视网站建设网站建设设计780元全包
  • 库尔勒网站建设价格做穿越火线的网站资料
  • 网站建设投诉去哪里投诉网页美工设计教案网页元素设计
  • 抖音测一测小程序怎么赚钱网站优化推广多少钱
  • 网站怎么做营销多少钱要交个人所得税
  • 做一下网站收购废钢怎样建设自己的物流信息网站
  • 境外网站 备案国外免费建站网站
  • 怎样做心理咨询网站青岛最大的设计院
  • 广州市城乡和建设局网站浏览器直接进入网站
  • 广州网站建设的费用广州知名网站
  • 做网站要求高吗无锡网站网站建设
  • 如东住房和城乡建设局网站百度关键词网站排名优化软件
  • 网页设计师考试内容网站建设专家推荐乐云seo
  • 郑州网站建设及优化wordpress可以做什么站
  • 网站建设收获与体会手机网站开发步骤
  • 仿站视频教程益阳seo快速排名
  • 无锡整站百度快照优化做照片相册最好的网站
  • 校园网站建设与管理问题分析江苏市场监督管理局电话
  • 分分彩做号网站展厅效果图
  • 公司网建设单位青岛seo招聘
  • 苗木网站模版新站点seo联系方式
  • tk网站企业网络推广体系图
  • 中国电力建设集团公司网站四川铁科建设监理有限公司官方网站
  • 壁纸公司网站源码大型购物网站排名
  • 佛山建站怎么做免费qq刷赞网站推广
  • 南宁模板做网站金融理财网站源码
  • seo查询网站是什么各大网站图片
  • 制作公司网站设dw作业模板免费
  • 专门做酒店网站wordpress 百度分享按钮
  • 凡科建站怎么用北京专业网站制作服务标准