简介

race condition是多线程的应用程序中经常遇到的问题,本文章接下来会解释什么是race condition,如何检测到它们以及如何解决这类问题。

Race condition

从定义来说,race condition是代码中一些执行结果取决于其执行的相对时间或者多线程交错执行的判断条件。它的结果是不可预测的。如何一个程序中不存在race condition,那么它就是线程安全的(thread-safe)。

例如有个转账程序,假设有两个账户,里面的余额都是500,现在要分两次从A账户转账300到B账户,如下图:

这两次转账操作分别有一个线程执行。如果第二次转账是在第一次转账后发生的,那么第二次转账就会判断发现A账户余额不足,从而转账失败。

但是,如果这两次转账在两个线程内同时执行,那么就可能出现不可预测的结果。如下图,两个线程检查A账户月都是500,都进行了转账操作,结果A账户最后余额是-100,这样的结果明显是不正确的。

如上转账过程,由于线程的执行时机是任意的,所以执行的结果也是不可预测的。造成这一情况的正是race condition(上面判断账户是否大于300的判断)。为了避免race condition,所以的共享资源(在例子中两个账户的余额可以被多个线程读取操作,所以余额就是共享资源)必须原子性地操作。打到这个目标有两个方法,第一种是将多个操作封装成一个线程排他性的代码段(例如加锁),第二是从硬件上保证是这些操作的原子性。

Race condition的两个模式

Check-Then-Act

Race condition有两个模式,第一个就是上面的转账的例子,属于Check-Then-Act模式,这类模式通常是一个流程中有一个检查环节,通过检查的结果再决定后续怎么走。

懒加载是Check-Then-Act的第二例子,例如在单例模式中,懒汉模式如下:

class Singleton {public static Object singleton;public static Object getSingleton(){if (singleton == null) {singleton = new Object();}return singleton;}
}

上面的singleton == null就是一个race condition,根据上面的解决办法,最简单是加上synchronized关键字,让判断和赋值两个操作具有线程排他性。

Read-Modify-Write

Read-Modify-Write是race condtion的第二个模式。在大多数编程语言中,对一个变量的修改通常分为读取,修改,写入三个步骤。问题通常是对变量的并发的读取修改(至少有一个修改,纯读取是没问题的)引起的。例如:

由于count++不是原子操作,所以可能发生以下情形:

两个线程同时对count进行++操作,结果并没有加2。

如何检测race condition

race condition通常很难重现,定位和排除,因为问题发生依赖于特定的场景。即使写一个多线程的单元也不可以保证程序的100%的正确定,但有一些方法可以排除race condition。

如何避免race condition

1.避免使用共享变量

在多线程环境中,race condtion的出现往往伴随着共享变量,如上面例子中的账户余额和count变量,都可以被多个线程读取操作,那么避免问题发生最简单直接的办法就是避免使用共享变量。可以使用不可变对象或者线程本地对象(例如java中的threadlocal)。

2.使用同步或者原子操作

使用同步可以避免race condition的问题,但是线程同步往往伴随很多同步的性能开销,还可能导致死锁。两个办法是使用原子操作,例如java中的提供的原子类。

什么是Race Condition?相关推荐

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

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

  2. python 很高兴问题_Python 3.7曾有一个很老的GIL竞态条件(race condition),我是这么解决的...

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 作者:Victor Stinner 作为Python最关键的组成部分之一:GIL(全局解释器锁),我花了4 ...

  3. 数据争用(data race) 和竞态条件(race condition)

    在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...

  4. Race Condition漏洞

    Race Condition Race Condition(竞争条件)是一种情形,在该情形下系统或者程序的输出受其他不可控事件的顺序或事件的影响.软件中的Race Condition通常出现在两个并发 ...

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

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

  6. java race condition_Java中的Race condition和Critical section(译)

    Java中的Race condition和Critical section(译) race condition,即竞态,是一种可能发生于critical section中的特殊状态,critical ...

  7. Race condition

    在很多门课上都接触到race condition, 其中也举了很多方法解决这个问题.于是想来总结一下这些方法. Race condition 它旨在描述一个系统或者进程的输出依赖于不受控制的事件出现顺 ...

  8. (转)Race condition解决

    在很多门课上都接触到race condition, 其中也举了很多方法解决这个问题.于是想来总结一下这些方法. Race condition 它旨在描述一个系统或者进程的输出依赖于不受控制的事件出现顺 ...

  9. 竞态条件(race condition)

    在学习多线程的过程中,因为是非科班学生,操作系统的东西都是一知半解的,所以很多名词都没有理解,另外具体的Java虚拟机如何工作还需要后续的学习,这里只能慢慢学习了,等到这本书看完好好读读操作系统的东西 ...

最新文章

  1. 跟着柴毛毛学Spring(3)——简化Bean的配置
  2. NHibernate: Session.Save 采用版本控制时无必要地自动Update版本字段的问题
  3. 百度网络推广总结大家在做页面标题优化时需注意的事项!
  4. 狼羊菜过河问题深入学习分析——Java语言描述版
  5. PHP Redis 集群封装类
  6. 51单片机复习:DS1302
  7. android 自定义spnner弹出框,PopupWindow,ListView实现自定义Spinner
  8. 递归法:递归实现排列型
  9. JAVA基础编程练习题--50道
  10. Tomcat内存溢出的三种情况及解决办法分析
  11. 恢复计算机个性化设置方法,Win7主题默认还原电脑用了主题软件没办法恢复完美解决系统主-win7主题...
  12. 阿里云短信接口配置教程
  13. 项目经理不得不知道的里程碑计划及其重要用途
  14. OSG学习:OSG组成(二)——渲染状态和纹理映射
  15. 友价T5商城系统一键生成SiteMap网站地图插件【chajian_sitemap_builder.php】
  16. python 面向对象终极进阶之开发流程
  17. 从零开始的Java再学习-DAY10
  18. 2007上海户口评分标准
  19. 弹性云服务器的规格系列,新睿云简析云服务器的配置规格怎么选择?
  20. #创新应用#图钉:记录人生的足迹

热门文章

  1. 遇到The import org.apache.commons cannot be resolved 的报错
  2. 常见的DNS攻击与相应的防御措施
  3. GPS卫星的导航电文和卫星信号
  4. 编译原理 —— 逆波兰式
  5. 天翼云 杭州 云主机(VPS) 性能评测
  6. 2018吉林CCPC(HDU6555)A.The Fool
  7. 模型预测控制(MPC)解析(十一):变量约束的预测控制
  8. 一个业务型算法工程师的技能清单
  9. 销售漏斗是什么?有什么作用!
  10. java修饰符(转)