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

深圳移动网站建站wordpress heroku

深圳移动网站建站,wordpress heroku,中国商标网注册官网,企业微信公众号注册平台官网前言 前面我们讲到了简单的线程安全问题以及简单的解决策略 其根本原因是cpu底层对线程的抢占式调度策略,随机调度 其他还有一些场景的问题如下 1.多个线程同时修改一个变量问题 2.执行的操作指令本身不是原子的 比如自增操作就分为三步,加载,自增,保存 3.内存可见性问题 4.指令…前言 前面我们讲到了简单的线程安全问题以及简单的解决策略 其根本原因是cpu底层对线程的抢占式调度策略,随机调度 其他还有一些场景的问题如下 1.多个线程同时修改一个变量问题 2.执行的操作指令本身不是原子的 比如自增操作就分为三步,加载,自增,保存 3.内存可见性问题 4.指令重排序问题 下面两个问题将会在本文中被解决 前面我们说到了解决几个线程同时修改一个变量的问题,我们使用加锁的方式来解决 使用synchronized关键字 特殊用法:用synchronized修饰普通方法,此时同步监视器就变为了this 修饰静态方法的时候此时相当于使用类对象当做同步监视器 synchronized加的锁也可以称为互斥锁 1.synchronized的一些其他特性 先举个例子 public class ThreadDemo21 {public static void main(String[] args) {Object lock new Object();Thread t1 new Thread(()-{synchronized (lock){synchronized (lock){System.out.println(hello);}}});t1.start();} } 这里我们直观上感觉,t1先持有了这个lock锁,此时在没有释放的情况下再进行加锁理论上应该会出现阻塞的情况,但是实际上并没有阻塞.这里的线程是会正确执行的? 为什么呢??? 这是因为这里的两次加锁是同一个线程进行的,所以第二次锁实际上并没有添加,只是真正加了一次锁,第二次加锁实际上是以计数器的形式自增一次,而并没有真正的加锁,所以释放的时候也释放了一次. 有人问这有啥用呢??? 其实是为了我们在写一些复杂逻辑的代码中可能会忘了这些加锁的过程,从而导致以上的阻塞的情况(称为死锁) 这个时候其实就巧妙的解决了问题,比如说如下情况 此时这种锁的机制称为可重入锁的机制 2.三种经典的死锁场景 1.一个线程一把锁 也就是我们刚刚讨论的场景,如果这个时候锁没有这个可重入锁的机制,我们就会发生死锁问题. 2.两个线程两把锁 举个例子,这里假设线程1拿到a锁,想获取b锁,同时线程2拿到b锁想获取a锁,此时两者都在等另一个线程释放另一个锁,就发生了僵持的效果 你可以想象两者发生一个交易,一个想先交钱,一个想先交货,两个人一直僵持而迟迟不能完成交易. public class ThreadDemo23 {private static final Object lock1 new Object();private static final Object lock2 new Object();public static void main(String[] args) {Thread t1 new Thread(()-{synchronized (lock1){try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2){System.out.println(t1我拿到了两个锁);}}});Thread t2 new Thread(()-{synchronized (lock2){try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock1){System.out.println(t1我拿到了两个锁);}}});t1.start();t2.start();} } 此时加上两个sleep是因为,希望在获取对应锁执行希望对应的一方获取到了对应的锁,此时执行就会发生僵持的效果 上述想解决僵持效果只需要将其中的一个线程的获取锁顺序的 3.n个线程m把锁 这里就涉及到一个哲学家进餐的问题 由Dijkstra提出并解决的哲学家就餐问题是典型的同步问题。该问题描述的是五个哲学家共用一张圆桌分别坐在周围的五张椅子上在圆桌上有五个碗和五只筷子他们的生活方式是交替的进行思考和进餐。平时一个哲学家进行思考饥饿时便试图取用其左右最靠近他的筷子只有在他拿到两只筷子时才能进餐。进餐完毕放下筷子继续思考。 这个时候,加入五个人同时想进餐,这个时候就会发生每个人都拿到一只筷子,而不愿意放下,这就构成了一个死锁 谈解决方案之前,我们要先讨论一下构成死锁的四个必要条件 1.互斥使用,使用锁的过程是互斥的,一个线程拿到这个锁就,另一个线程想要获取就得阻塞等待 2.不可抢占 一个线程获取这个锁,只能等其他的线程主动释放 3.请求保持 持有a获取b 4.环路等待 这里1和2都不太容易破坏,只有3和4方便破坏 3可能是代码业务逻辑需求的 所以此时修改4是最合理的 此时想解决这个问题,提出几个思路 1.去掉一个哲学家 2.增加一支筷子 3.引入计数器,限制同时可以支持多少个人一起吃吃面 4.引入加锁的规则(较为常用,这里就可以控制获取筷子的顺序,此时给筷子排上编号,只能先获取编号小的筷子,此时2号获取了筷子1,以此类推,最后5获取了两个筷子,最后他结束了,其他线程/哲学家就可以吃到饭了) 5.银行家算法(太过复杂,一般不用) 3.内存可见性问题 老样子,先举个例子 public class ThreadDemo22 {private static int flag 0;public static void main(String[] args) {Thread t1 new Thread(()-{while(flag 0){}System.out.println(线程结束!);});Thread t2 new Thread(()-{System.out.println(请输入一个数字);Scanner sc new Scanner(System.in);flag sc.nextInt();});t1.start();t2.start();} }此时我们想进行修改flag为任何值都发现是不成功的 这是因为,flag 0这个操作分为两个指令 1.从内存中读取flag的值到寄存器中 2.读取完和0进行比较,然后进行一个跳转 在我们输入这个数字之前,其实这个while循环已经实现了很多次了 在这两个指令中,比较是没有多大开销的,然而从内存中加载的开销是比较大的 JVM认为这么多次这个变量始终没有修改,为了提高效率,直接把这个加载的动作直接优化掉了 其实可以理解为JVM的一个bug,此时我们可以使用sleep(n)让这个加载的频率降低,这样就不会优化了.但是治标不治本我们这里引入一个新的关键字volatile 用这个关键字来修饰flag就会让其强制读取内存,这样的结果就会更精确!! 网上还有一个说法就是将这里的内存(缓存)和寄存器的概念换成了主存和工作内存的概念,显得更严谨.
http://www.huolong8.cn/news/29099/

相关文章:

  • 做网站顺序百度引擎入口官网
  • 网站机房建设做个网站 多少钱
  • 网站开发公司如何拓展业务网站插件模块原理
  • 深圳网站快速排名优化用中文版wordpress建英文站
  • 怎么看一个网站做没做优化能看建设动漫黄图的网站
  • 火车头采集做网站赚钱岳阳网站优化
  • 网站打不开怎么做移动商城型网站开发
  • 常平镇网站建设公司国外设计网站dooor
  • 广州站停运最新消息网络热词缩写
  • 免费游戏网站建设游戏后台做网站标准步骤
  • 深圳网站设计收费标准html购物网站源码
  • 长沙网站制作哪怎么做搜索网站
  • 企业网站怎么做推广做网站用语言
  • 上传文档网站开发平台公司实体化转型
  • 大型网站开发人员广州seo排名外包
  • 政务网站建设情况汇报河北一建停考
  • 秦皇岛工程建设信息网站水果网站开发所需的成本
  • 像饿了码的网站建站有吗网站建设中标签导航的特征
  • 北镇网站建设网站开发 发表文章
  • 专业网站建设技术网站建设的定位
  • 网站上面的头像怎么做的安康做网站公司
  • 网站和网页有什么区别汇鑫小学网站建设
  • 叫别人建个网站多少钱wordpress单页制作
  • 网站忘记备案做一个公众号多少钱
  • 查信息的网站有哪些郑州全域静态管理
  • 亚马逊中国官网网站济南建站价格
  • 做门户网站代码质量方面具体需要注意什么百度付费推广
  • 海南旅游网站开发背景重庆地推团队外包
  • 常州个人网站建设建站行业消失了吗
  • 湖南省建设工程造价总站网站中瑞网络网站建设流程