Java中的Race condition和Critical section(译)

race condition,即竞态,是一种可能发生于critical section中的特殊状态,critical section一般翻译为临界区,我个人认为临界区不是很直观,因此不做翻译,仍然用英文。这里的critical section实际上是一个可能会被多个线程并发执行的代码区段,并发线程的不同执行顺序会直接影响整个并发程序的执行结果。

由于并发线程的不同执行顺序直接影响这部分代码的执行结果,这时我们就说这部分代码为critical section,而critical section的代码被多个线程并发执行的时候,则处于被竞争执行的状态,即race condition。

Critical section

事实上,同一段代码在多个线程并发执行时并不一定会引发问题,而是在多个线程同时竞争访问共享的资源时才有可能引发race condition。这里的资源包括内存资源(变量,数组或对象等),系统资源(数据库,web服务等)以及文件等。

实际上只有多个线程并发对共享的资源进行写操作时才有可能引发问题。多个线程读共享资源并不会引发什么问题。

下面的这段代码是一个critical section例子,多线程并发执行时会引发问题:

假设两个不同的线程A和B,通过一个相同的Counter对象,并发执行该对象的add方法。操作系统何时进行线程的切换是不确定的。add方法内部的这行代码编译成字节码在JVM内部执行时并不是一个原子操作,而是分解成了类似如下所示的几个字令来执行:

1、 从主内存将this.count读到CPU的寄存器内;

2、 将value值加到寄存器的值;

3、 将寄存器内的值写回到主内存。

将这个过程,对应到两个两个线程A、B并发执行,则可能以如下的顺序进行执行:

本来这两个线程A,B是想将2和3加到count上,预期的结果应该是5才对。但是由于这两个线程是并发交叉执行的,导致线程A的计算结果3最终写回到主内存,同时也覆盖了现场B写会到主内存的2。执行结果不符合预期。当然,这里假象出来的这个执行流程只是一种可能发生的情况,也有可能执行结果是2或5。但是只要有这种竞态发生的可能性,这种代码段就是critical section,是我们需要极力杜绝的。

如何避免race condition

那么我们如何避免race condition的发生呢?答案是原子性。

我们需要将有可能发生竞态的critical section包成一个原子操作,即如果一个线程正在执行这部分代码,那么其他线程只能等到该线程结束执行离开后才能开始执行。

具体来说,我们可以通过一些线程之间相互同步的手段来实现。比如:

1、 synchronized代码块;

2、 锁;

3、 原子性变量,如java.util.concurrent.atomic.AtomicInteger。

critical section的吞吐量

对于逻辑简单的critical section,通过synchronized代码块来避免竞态没啥问题,但是对于逻辑复杂、代码量大的critical section来说,这种方式无疑会降低整个系统的吞吐量。这时我们可以尝试将其拆解成多个独立的、较小的critical section。

举个例子:

这里我们为了避免竞态的放生,用synchronized将代码段包了下。这样在多线程并发执行时,这些线程只能挨个轮流执行该代码段。但是我们细想就会发现,这个代码段其实可以拆分成两个独立的、互不影响的子代码段:

这样如果两个线程并发执行add方法,则可以再一个线程执行第一个子代码段的同时另一个线程执行第二个代码段,因此避免了更长时间的相互等待,提升了吞吐量。

当然,这个例子非常简单,仅为了说明原理,实际项目中可能需要更加认真的分析才知道如何进行拆分。

java race condition_Java中的Race condition和Critical section(译)相关推荐

  1. java race condition_java 多线程下race condition问题

    这个问题的讨论来自内部的一个关于"多线程环境下使用Hashmap的安全问题"的讨论,HashMap多线程的问题之前已经提过一次,见之前的blog.本篇文章主要讨论多线程下race ...

  2. java的condition_java并发编程之Condition

    引言 在java中,对于任意一个java对象,它都拥有一组定义在java.lang.Object上监视器方法,包括wait(),wait(long timeout),notify(),notifyAl ...

  3. java race condition_java多线程(一)Race Condition现象及产生的原因

    什么是Race Condition 首先,什么是Race Condition呢,Race Condition中文翻译是竞争条件,是指多个进程或者线程并发访问和操作同一数据且执行结果与访问发生的特定顺序 ...

  4. java lock condition_Java 通过 Lock 和 竞争条件 Condition 实现生产者消费者模式

    更多 Java 并发编程方面的文章,请参见文集<Java 并发编程> 竞争条件 多个线程共享对某些变量的访问,其最后结果取决于哪个线程偶然在竞争中获胜. condition.await() ...

  5. 详解Java多线程编程中LockSupport类的线程阻塞用法

    转载自  详解Java多线程编程中LockSupport类的线程阻塞用法 LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport实际 ...

  6. 【Java】NIO中Selector的select方法源码分析

    该篇博客的有些内容和在之前介绍过了,在这里再次涉及到的就不详细说了,如果有不理解请看[Java]NIO中Channel的注册源码分析, [Java]NIO中Selector的创建源码分析 Select ...

  7. [转载] c++多态与java多态性_Java中的多态性

    参考链接: Java中的加法和串联 c++多态与java多态性 Polymorphism is one of the core concepts of OOPS paradigm. The meani ...

  8. java中的多态性_[转载] c++多态与java多态性_Java中的多态性

    参考链接: Java中的加法和串联 c++多态与java多态性 Polymorphism is one of the core concepts of OOPS paradigm. The meani ...

  9. c++多态与java多态性_Java中的多态性

    c++多态与java多态性 Polymorphism is one of the core concepts of OOPS paradigm. The meaning of polymorphism ...

最新文章

  1. kafka和storm集群的环境安装
  2. 高防御服务器与高防御IP之间的关系
  3. 由于检索用户的本地应用程序数据路径时出错,导致无法生成 SQL Server 的用户实例...
  4. 如何通俗理解拉格朗日对偶问题(part1)
  5. 解决:building 'twisted.test.raiser' extension安装scrapy报错
  6. [bzoj4994][Usaco2017 Feb]Why Did the Cow Cross the Road III_树状数组
  7. Layer 2 DAO 基础协议 Metis 上线 Alpha 测试网
  8. VSCode打开底部状态栏
  9. 模拟电路设计经典教材推荐
  10. 飞秋远程可利用0day 的详细分析和利用方法 飞秋漏洞
  11. lstm实战,nlp情感分析(Kaggle)
  12. 全栈式PHP集成环境-laragon(二) 配置、使用
  13. 通过NVIDIA-Docker部署深度学习项目环境
  14. PPT格式转换PDF在手机上如何操作
  15. html中实现页面跳转代码怎么写,用JavaScript怎么实现页面跳转?
  16. 数据可视化-echarts入门、常见图表案例、超详细配置解析及项目案例
  17. typescript egg mysql_Egg.js egg-mysql 连接MySQL 报 AppWorkerDiedError 错误
  18. 笑谈,人兽分界线 多贝网课程分享
  19. 51单片机串口通讯c语言程序,如何使用51单片机实现串口通信
  20. cocos2d-x 3.2 |飞机大战:飞机与子弹

热门文章

  1. postman--断言写法
  2. 阿里巴巴2015秋季校园招聘研发工程师在线笔试题
  3. ZigBee、WiFi、蓝牙的区别
  4. 文字禅、看话禅、默照禅与念佛禅(轉)
  5. Learning Entity and Relation Embeddings for Knowledge Graph Completion (TransR)论文翻译
  6. Codeforces 676D Theseus and labyrinth 模拟+bfs
  7. 阿里的“传奇程序员”
  8. delphi 中的浮点数 (转载)
  9. 业务模块卸载失败定位过程
  10. C陷阱与缺陷-疑难问题理解06