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

医院网站制作好吗合肥seo推广外包

医院网站制作好吗,合肥seo推广外包,建设行业网上报名,酒店专业培训网站建设点击上方蓝色文字关注我吧一个或者多个操作在 CPU 执行的过程中不被中断的特性,称为“原子性”。原子性问题到底该如何解决呢?原子性问题的源头是线程切换。“同一时刻只有一个线程执行”这个条件非常重要,我们称之为互斥。如果我们能够保证对…
9a0743664bf77cc31ea0963582384ffb.png

点击上方蓝色文字关注我吧

9a0743664bf77cc31ea0963582384ffb.png

一个或者多个操作在 CPU 执行的过程中不被中断的特性,称为“原子性”。

原子性问题到底该如何解决呢?

原子性问题的源头是线程切换。“同一时刻只有一个线程执行”这个条件非常重要,我们称之为互斥。如果我们能够保证对共享变量的修改是互斥的,那么,无论是单核 CPU 还是多核 CPU,就都能保证原子性了。

Java 语言提供的锁技术:synchronized

锁是一种通用的技术方案,Java 语言提供的 synchronized 关键字,就是锁的一种实现。synchronized 关键字可以用来修饰方法,也可以用来修饰代码块,它的使用示例基本上都是下面这个样子:

class X {  // 修饰非静态方法  synchronized void foo() {    // 临界区  }  // 修饰静态方法  synchronized static void bar() {    // 临界区  }  // 修饰代码块  Object obj = new Object();  void baz() {    synchronized(obj) {      // 临界区    }  }}  

看完之后你可能会觉得有点奇怪,这个和我们上面提到的模型有点对不上号啊,加锁 lock() 和解锁 unlock() 在哪里呢?其实这两个操作都是有的,只是这两个操作是被 Java 默默加上的,Java 编译器会在 synchronized 修饰的方法或代码块前后自动加上加锁 lock() 和解锁 unlock(),这样做的好处就是加锁 lock() 和解锁 unlock() 一定是成对出现的,毕竟忘记解锁 unlock() 可是个致命的 Bug(意味着其他线程只能死等下去了)。

那 synchronized 里的加锁 lock() 和解锁 unlock() 锁定的对象在哪里呢?上面的代码我们看到只有修饰代码块的时候,锁定了一个 obj 对象,那修饰方法的时候锁定的是什么呢?这个也是 Java 的一条隐式规则:

当修饰静态方法的时候,锁定的是当前类的 Class 对象,在上面的例子中就是 Class X;

当修饰非静态方法的时候,锁定的是当前实例对象 this。

对于上面的例子,synchronized 修饰静态方法相当于:

class X {  // 修饰静态方法  synchronized(X.class) static void bar() {    // 临界区  }}修饰非静态方法,相当于:class X {  // 修饰非静态方法  synchronized(this) void foo() {    // 临界区  }}

用 synchronized 解决 count+=1 问题

相信你一定记得我们提到过的 count+=1 存在的并发问题,现在我们可以尝试用 synchronized 来小试牛刀一把,代码如下所示。SafeCalc 这个类有两个方法:一个是 get() 方法,用来获得 value 的值;另一个是 addOne() 方法,用来给 value 加 1,并且 addOne() 方法我们用 synchronized 修饰。那么我们使用的这两个方法有没有并发问题呢?

class SafeCalc {  long value = 0L;  long get() {    return value;  }  synchronized void addOne() {    value += 1;  }}

我们先来看看 addOne() 方法,首先可以肯定,被 synchronized 修饰后,无论是单核 CPU 还是多核 CPU,只有一个线程能够执行 addOne() 方法,所以一定能保证原子操作,那是否有可见性问题呢?要回答这问题,就要重温管程中锁的规则:对一个锁的解锁 Happens-Before 于后续对这个锁的加锁。

管程,就是我们这里的 synchronized,我们知道 synchronized 修饰的临界区是互斥的,也就是说同一时刻只有一个线程执行临界区的代码;而所谓“对一个锁解锁  Happens-Before 后续对这个锁的加锁”,指的是前一个线程的解锁操作对后一个线程的加锁操作可见,综合 Happens-Before 的传递性原则,我们就能得出前一个线程在临界区修改的共享变量(该操作在解锁之前),对后续进入临界区(该操作在加锁之后)的线程是可见的。

按照这个规则,如果多个线程同时执行 addOne() 方法,可见性是可以保证的,也就说如果有 1000 个线程执行 addOne() 方法,最终结果一定是 value 的值增加了 1000。看到这个结果,我们长出一口气,问题终于解决了。

但也许,你一不小心就忽视了 get() 方法。执行 addOne() 方法后,value 的值对 get() 方法是可见的吗?这个可见性是没法保证的。管程中锁的规则,是只保证后续对这个锁的加锁的可见性,而 get() 方法并没有加锁操作,所以可见性没法保证。那如何解决呢?很简单,就是 get() 方法也 synchronized 一下,完整的代码如下所示。

class SafeCalc {  long value = 0L;  synchronized long get() {    return value;  }  synchronized void addOne() {    value += 1;  }}

上面的代码转换为锁模型,就是下面图示这个样子。get() 方法和 addOne() 方法都需要访问 value 这个受保护的资源,这个资源用 this 这把锁来保护。线程要进入临界区 get() 和 addOne(),必须先获得 this 这把锁,这样 get() 和 addOne() 也是互斥的。

2361690b8eeb90a3546b2303a4ae70f7.png

护临界区 get() 和 addOne() 的示意图

锁和受保护资源的关系

我们前面提到,受保护资源和锁之间的关联关系非常重要,他们的关系是怎样的呢?一个合理的关系是:受保护资源和锁之间的关联关系是 N:1 的关系。

现实世界里,我们可以用多把锁来保护同一个资源,但在并发领域是不行的,并发领域的锁和现实世界的锁不是完全匹配的。不过倒是可以用同一把锁来保护多个资源。

上面那个例子我稍作改动,把 value 改成静态变量,把 addOne() 方法改成静态方法,此时 get() 方法和 addOne() 方法是否存在并发问题呢?

class SafeCalc {  static long value = 0L;  synchronized long get() {    return value;  }  synchronized static void addOne() {    value += 1;  }}

如果你仔细观察,就会发现改动后的代码是用两个锁保护一个资源。这个受保护的资源就是静态变量 value,两个锁分别是 this 和 SafeCalc.class。我们可以用下面这幅图来形象描述这个关系。由于临界区 get() 和 addOne() 是用两个锁保护的,因此这两个临界区没有互斥关系,临界区 addOne() 对 value 的修改对临界区 get() 也没有可见性保证,这就导致并发问题了。

ccd79d308091e4e0165321736d4eef61.png

两把锁保护一个资源的示意图

总结

synchronized 是 Java 在语言层面提供的互斥原语,其实 Java 里面还有很多其他类型的锁,但作为互斥锁,原理都是相通的:锁,一定有一个要锁定的对象,至于这个锁定的对象要保护的资源以及在哪里加锁/解锁,就属于设计层面的事情了。

精彩回顾d977832bece4f658c59ad26d0fd2c325.gif

并发编程Bug的源头-可见性

d977832bece4f658c59ad26d0fd2c325.gif

‍‍并发编程Bug的源头-原子性‍‍

d977832bece4f658c59ad26d0fd2c325.gif

并发编程Bug的源头-有序性

d977832bece4f658c59ad26d0fd2c325.gif

Java内存模型

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

相关文章:

  • 网站建设 成功案例seo自学网app
  • 网站建设策划长沙网络推广外包费用
  • 昆明网站建设公司电话谷歌seo培训
  • 百度网站的网址在线客服系统
  • 怎么让人搜索到自己做的网站2345网址导航桌面版
  • 金华企业自助建站系统友链交换平台
  • 建网站需要备案吗百度网络营销的概念
  • 怎么用自己的服务器做网站免费网站代理访问
  • 网站建设ftp蔡甸seo排名公司
  • 做色流网站要注意什么地方推广产品的方式有哪些
  • 做网站 图片素材怎么找收录查询工具
  • 天津商务网站建设网络关键词
  • 个人网站免费模板百度账户代运营
  • 青岛网站建设首选营销吧系统西安seo关键词查询
  • 公司要制作网站域名大全免费网站
  • 河北信息门户网站定制优化设计三年级下册数学答案
  • 做网站流程网站seo的优化怎么做
  • 高端网站建设网站定制网站内容seo
  • 外贸中间体做哪个网站好如何让百度快速收录新网站
  • 2018年网站建设网站百度收录突然消失了
  • 江门学做网站课程在线资源链接
  • 佛山网站建设外包网站安全查询系统
  • 做企业网站怎么备案茂名网络推广
  • 网站上的地图导航怎么做营销策略有哪些
  • 蜘蛛爬网站百度推广一天烧多少钱
  • 张家港做政府网站的公司seo公司软件
  • 网站设计什么样风格会高端些网站登录入口
  • 申请一个电子邮箱搜索引擎优化是什么工作
  • 做鞋子批发的网站有哪些域名注册信息怎么查
  • 在环评备案网站上做登记后会怎么样各类资源关键词
  • android直连SQLserver的可行性分析
  • TCP协议与UDP协议
  • MongoDB 从3.4.0升级到4.0.0完整指南实战-优雅草蜻蜓I即时通讯水银版成功升级-卓伊凡|bigniu
  • Bean的生命周期和循环依赖问题的解决
  • 链表问题解决分析框架
  • 鸿蒙开发-端云一体化--云数据库