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

山东省建设发展研究院网站wap浏览器模拟

山东省建设发展研究院网站,wap浏览器模拟,重庆网站推广转化率,合肥建设官方网站​ #x1f495;命由我作#xff0c;福自己求#x1f495; 作者#xff1a;Mylvzi 文章主要内容#xff1a;线程学习(2)​​​​ 一.volatile关键字 volatile关键字是多线程编程中一个非常重要的概念#xff0c;它主要有两个功能#xff1a;保证内存可见性… ​ 命由我作福自己求 作者Mylvzi 文章主要内容线程学习(2)​​​​ 一.volatile关键字 volatile关键字是多线程编程中一个非常重要的概念它主要有两个功能保证内存可见性和禁止指令重排序 1.内存可见性 内存可见性(Memory Visibility) 指的是在多线程编程环境下一个线程修改共享变量其他线程能够立即看到共享变量修改后的值 先来了解一个底层知识我们写的代码是要读取数据的最常见的数据就是我们定义的变量变量被保存在内存之中系统要使用数据需要cpu进行读内存(load)的操作,而load这个操作对于cpu来说是一个非常慢的数据因为cpu的速度是很快的读内存这个操作比读寄存器要慢上几千倍所以load对于cpu来说是一个很大的开销 // 设计一个标志位 private static int isQuit 0;Thread t1 new Thread(() - {while(isQuit 0) {// ...... }System.out.println(t1线程结束); });// 在t2线程中修改isQuit的值 Thread t2 new Thread(() - {System.out.println(请输入isQuit的值);Scanner scan new Scanner(System.in);isQuit scan.nextInt(); });t1.start(); t2.start();结果截图 在t2中将isQUit设置为1按理说t1中的循环条件已经不满足了啊整个进程应该会终止才对但是什么都没有打印,这是为什么呢这其实就和我们上面说的读内存对cpu开销大这一事实有关 先说结论为了解决读内存的问题并提高效率编译器会对读取数据进行一些优化减少读内存的次数尽可能多的直接从cpu上读取来提高效率 知道了这个结论就很容易解释上述问题了 编译器是好心的但是他为了提高效率却忽视了准确性而这个准确性对我们来说是很重要的(这涉及到整个进程的执行)不能忽视。这也属于一个编译器的bug 而关键字volatile就是用于解决这个问题被volatile修饰的变量编译器不会对其执行上述的优化,也就是告诉编译器我这个变量很重要不要为了效率就忽视准确性。 当我们在t2线程中修改变量isQuit时实际上是内存中的isQuit发生了改变其他线程(t1)能够立即看到这个改变后的值,循环终止这就是volatile关键字的内存可见性功能它保证了共享变量在所有线程中的公开透明其他线程能够立即看到共享变量的改变及时做出调整。 在输入1之后t1线程结束循环立即终止 内存可见性也是线程安全问题的一种之前学习过的一个线程安全问题是两个线程同时针对同一个变量进行修改但实际上两个线程一个线程修改变量一个线程读取变量可能也会发生线程安全问题 再补充一点,编译器之所以进行优化是因为短时间内大量的load操作.如果我们放慢/减少 load,编译器就不会进行优化,最常见的方式就是添加sleep Thread t1 new Thread(() - {while(isQuit 0) {// 让线程休眠一会儿try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}// ......}System.out.println(t1线程结束);});运行结果: 由于t1内部让线程短暂阻塞了一会儿,load操作执行的次数就会大大减少,此时编译器就没有进行优化的必要,所以每次读取都是读内存. 补充 volatile的本意是不稳定的,易挥发的,使用它修饰一个变量相当于告诉编译器喂(#O′),我这个变量是不稳定的啊,你不要把他给我加载到工作内存(cpu寄存器)中,让他老老实实的代码主内存中就行,这样编译器就不会进行优化了 2.指令重排序 指令重排序也是编译器优化的一种,它是指在保证执行结果正确的前提下,对指令的执行顺序进行调整,达到效率提高的目的,比如去菜市场买菜,我只要最后买到我要买的菜即可,我按照什么路径去买无所谓,但是我追求最快买完 在单线程模式下,指令重排序不会带来问题,反而还是一个好处.但是在多线程下,由于线程的调度是随机的,就有可能带来意想不到的 结果,所以我们需要禁止指令的重排序,往往是对可能涉及到指令重排序对象进行volatile的修饰,就能让编译器不对其进行优化 关于指令重排序 的具体应用会在后面的单例模式部分讲到 二.wait/notify 1.引言 在多线程编程中,我们经常要协调线程的执行顺序来实现一些场景需求,比如之前学习过的join()方法,他可以控制线程的结束顺序,也是协调线程的一种方式 但是有些时候我们想线程不结束,也能控制他们的执行顺序.而不是只能等到一个线程结束再去执行其他线程,此时,就可以使用wait/notify来实现上述需求 2.wait方法的使用 wait和notify方法都是属于Object类的方法,需要通过实例化一个object对象来进行调用 wait方法的具体执行过程分为三步: 释放当前对象的锁阻塞等待等待对象使用notify方法唤醒 wait方法使用的过程中有一个最常见的错误就是调用wait方法的对象事先并没有加锁,直接wait会报错 public static void main(String[] args) throws InterruptedException {Object locker new Object();System.out.println(wait 开始);locker.wait();System.out.println(wait 结束);}运行结果: 这里显示**非法监视器状态异常**,监视器 是什么?我们之前学习过synchronized,他是用于给对象加锁的,他其实还有另一个名字,叫做 监视器锁. 更本质的说,监视器(monitor)其实是一种机制,每个对象都会关联一个监视器,用于实现同步,同步就是保证多个线程对于共享变量的使用是合理的,是没有线程安全问题的(比如使用加锁来实现同步,可以避免多个线程针对同一变量进行修改这种线程安全问题).我想,这里的同步的意思是指在多线程编程中,每个线程获取到的共享资源的状态是同步的,不会出现一个线程修改了共享变量,另一个线程却还在使用修改之前的变量. synchronized被称为监视器锁,是因为它本质上是获取到了对象关联监视器的锁,他保证了同一时间只能有一个线程访问进入synchronized修饰的代码块/方法,保证了线程安全. 回到本文,由于创建的locker对象事先并没有加锁,与其关联的监视器的锁并没有上锁,没有上锁你却想先释放锁,这不是bug吗,所以会报出非法监视器状态异常,为了解决这个异常,我们需要先对locker对象进行加锁 public static void main(String[] args) throws InterruptedException {Object locker new Object();synchronized(locker) {System.out.println(wait 开始);locker.wait();System.out.println(wait 结束);}}运行结果 注:wait方法也可以带参数,和带参数的join方法一样,可以设置等待的时间 3.notify方法的使用 wait方法会先释放调用对象的锁,然后使调用的线程处于阻塞状态,直到对象使用notify进行唤醒,notify在使用的时候也需要先获取到与对象关联的锁,否则也会抛出非法监视器状态异常,这样做也是为了保证线程安全 示例代码: public static void main(String[] args) {Object locker new Object();Thread t1 new Thread(() -{synchronized (locker) {System.out.println(wait 开始);try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(wait 结束);}});Thread t2 new Thread(() - {try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker) {System.out.println(使用notify 方法 进行唤醒);locker.notify();}});t1.start();t2.start();}运行结果: 除了使用notify,我们还可以使用notifyAll方法来一次性唤醒当前对象所有wait的线程,当然看似是一次性,实际上还是一个一个进行唤醒的,如果一次性唤醒全部,会导致锁冲突,出现线程不安全问题 今天的学习就到这里,下期预告多线程设计模式讲解(1)
http://www.pierceye.com/news/305233/

相关文章:

  • 喜茶品牌策划全案案例seo技术
  • 简速做网站中国企业网站建设案例
  • 做网站不给源码莱州网站建设包年多少钱
  • 好玩有趣的网站贵州省城乡建设厅网站材料价
  • 投资公司网站设计上海自动seo
  • 网络营销导向网站建设的基础是什么创新驱动发展战略的内容
  • 银狐鑫诺科技 网站建设深圳画册设计价格
  • 邵阳网站建设推广优化游戏性能的软件
  • wp做网站难吗销售产品单页面网站模板
  • 网站子域名 更换网站开发什么方式
  • 学做面食最好的网站设计公司logo大全
  • wordpress建站入门手机网站跳转怎么办
  • 好网站开发培训wordpress是否免费
  • 建设国际互联网网站网站建设制作流程
  • 开发一个网站做爬虫手机网站建设视频
  • 网站搜索功能模块公众号开发菜单
  • 公司想做个自己的网站怎么做网络营销与管理专业
  • 网站设计中国内优秀企业网站欣赏深圳商城网站设计公司
  • 泌阳县住房和城乡建设局网站wordpress注册去掉电子邮件
  • 电商网站设计目的活动策划怎么写
  • 做网站有限公司智慧团建官方网站
  • 南京建设网站公司哪家好科技创新论文800字
  • 网站app的区别是什么深圳沙井做网站公司
  • 珠海网站建站js写wordpress
  • 公司做网站怎么做账网站建设都需要买什么东西
  • seo网站模板深圳建设局和住建局
  • 全国做网站的公司有哪些正规网站做菠菜广告
  • 成都有哪些做公司网站的公司动漫制作专业用什么笔记本电脑
  • 模型外包网站网站建设费用 多少钱
  • 课程资源网站开发 jsp免费做网站自助建站