多线程+Race Condition现象及产生的原因
什么是Race Condition
首先,什么是Race Condition呢,Race Condition中文翻译是竞争条件,是指多个进程或者线程并发访问和操作同一数据且执行结果与访问发生的特定顺序有关的现象。换句话说,就是线程或进程之间访问数据的先后顺序决定了数据修改的结果,这种现象在多线程编程中是经常见到的。
Race Condition 实例
class MyThread implements Runnable {/*** 计算类型,1表示减法,其他的表示加法*/private int type;public MyThread(int type) {this.type = type;}public void run() {if (type == 1)for (int i = 0; i < 10000; i++)Test.num--;elsefor (int i = 0; i < 10000; i++)Test.num++;}
}public class Test {public static int num = 1000000;public static void main(String[] args) {Thread a = new Thread(new MyThread(1));Thread b = new Thread(new MyThread(2));a.start();b.start();/** 主线程等待子线程完成,然后再打印数值*/try {a.join();b.join();} catch (Exception e) {e.printStackTrace();}System.out.println(num);}}
上边的程序非常简单。就是用两个线程同时操作和修改同一个数据,一个线程希望把num加10000,另一个线程希望把num减小10000,根据我们的计算,一个数加上10000,再减去10000,相当于没有变化,所以结果应该等于他自身。但是这只是我们的想象,事实真的是这样吗?大家可以运行一下上边的程序,你会吃惊的发现,结果并不是1000000,再多运行几次,是不是每次的结果都不一样。
没错,这就是产生了Race Condition,有两个线程,同时操作num这个变量,并且操作的结果与访问的顺序有关(这个不是我们控制的,而是由操作系统控制的,我们只能看到每次的结果都不一样)。
Race Condition 产生的原因
现在我们已经看到了Race Condition现象了,那么它是怎么产生的呢?先不要急切的说,你不是说了吗,是由于访问顺序不同造成的。我想说,学习新知识一定要追根溯源,要真正的弄明白,那么在硬件或者操作系统层面上,这一现象发生的原因是什么呢?
首先,我们来看一张图。
我们知道,在操作系统中,操作系统程序为每个线程分配了单独的寄存器和程序计数器。在上边的图中,我一共分成了三列,其中第一列表示线程一的操作过程,第二列表示线程二的操作过程,第三列表示内存中的结果。图中前两列的写着数字的小方框表示该线程所使用的寄存器,数字表示该寄存器中的值。第三列的小方框表示内存中的 一个存储单元,数值表示内存中存储的数值。
现在,我们来看一下操作的过程。(这里是简化了的示意过程,真正的过程要复杂的多)开始时,数据都是放在内存中的,所以通过LOAD指令,将num加载到寄存器中,接着执行相应的操作指令,这里分别为ADD(加1) SUB(减1)指令,指令执行结束后,结果是存储在相应的寄存器中的,这时内存中的数值还没有发生变化。最后执行STORE指令之后,寄存器中的数值被存储到内存中。
小方框从上到下的顺序表示线程1和线程2交替执行的过程。首先,线程1读取了内存中num的值,然后换到线程2执行,先读取了内存中num的数值,然后执行减1操作,最后将结果写回内存中,这时内存中的数据变成了999999,但是这一个变化线程1是看不到的,因为这一变化发生在线程1读取num的值之后。其实这时线程1读取到的数据已经是不正确的数据了,这是产生Race Condition的根本原因。然后线程1接着执行未执行完的指令,加1操作,最后将1000001写会内存,这是产生Race Condition的直接原因,它将线程2的结果给覆盖掉了。
这就是Race Condition产生的原因,大家是不是真正的明白了呢?。
当然Race Condition这种现象是不好的,所以我们会通过各种途径来避免产生Race Condition。在接下来的博客里,我会为大家介绍如果在Java的多线程编程中避免出现Race Condition 以及多线程的同步和互斥的内容,希望与大家一起学习一起进步,请大家继续关注我的博客,如果大家支持我的话,就顶我一下吧。
转载出处http://blog.csdn.NET/xingjiarong/article/details/47603813
多线程+Race Condition现象及产生的原因相关推荐
- java race condition_java多线程(一)Race Condition现象及产生的原因
什么是Race Condition 首先,什么是Race Condition呢,Race Condition中文翻译是竞争条件,是指多个进程或者线程并发访问和操作同一数据且执行结果与访问发生的特定顺序 ...
- java race condition_java 多线程下race condition问题
这个问题的讨论来自内部的一个关于"多线程环境下使用Hashmap的安全问题"的讨论,HashMap多线程的问题之前已经提过一次,见之前的blog.本篇文章主要讨论多线程下race ...
- Race condition
在很多门课上都接触到race condition, 其中也举了很多方法解决这个问题.于是想来总结一下这些方法. Race condition 它旨在描述一个系统或者进程的输出依赖于不受控制的事件出现顺 ...
- (转)Race condition解决
在很多门课上都接触到race condition, 其中也举了很多方法解决这个问题.于是想来总结一下这些方法. Race condition 它旨在描述一个系统或者进程的输出依赖于不受控制的事件出现顺 ...
- 别混淆数据争用(data race) 和竞态条件(race condition)
在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...
- Race Condition(资源竞争) 解决方案总结
在很多门课上都接触到race condition, 其中也举了很多方法解决这个问题.于是想来总结一下这些方法. Race condition 它旨在描述一个系统或者进程的输出依赖于不受控制的事件出现顺 ...
- 数据争用(data race) 和竞态条件(race condition)
在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...
- OSCache 缓存重建在 Race Condition 下的 NRE 问题
OSCache 缓存重建在 Race Condition 下的 NRE 问题 一,现象: 高并发情况下,使用 OSCache 作为本地缓存中间件的前端服务,日志文件中会出现大量如下错误信息: 异常堆栈 ...
- python 很高兴问题_Python 3.7曾有一个很老的GIL竞态条件(race condition),我是这么解决的...
Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 作者:Victor Stinner 作为Python最关键的组成部分之一:GIL(全局解释器锁),我花了4 ...
最新文章
- 计算机显示器黑屏首先检查,蓝快干货 | 电脑黑屏的解决办法
- 零基础前端笔记(2)html,表格,列表,标签,文本域,表单域
- Spring Boot注册Servlet三大组件(Servlet, Filter, Listener)
- 验证网站地址是否有效
- python 各种推导式玩法
- 解决Linux系统没有/etc/sysconfig/iptables文件
- mysql中去重的用法_mysql中去重 distinct 用法
- linux分区转换gpt命令,Linux中磁盘如何转换GPT格式
- .Net Core中依赖注入服务使用总结
- 小知识--Windows语音效果
- synchronize偏向锁底层实现原理
- 开心网kaixin001状告kaixin,停用“开心网”名称,赔偿1000万元
- linux ls按着文件数字大小排列
- java sl4j 日志_java-slf4j日志文件保存在哪里?
- Abaqus安装CAE报错Regview解决方法
- 解析 | 自动驾驶视觉定位与导航技术的研究与应用
- matlab 绘图图例只有文字不显示线型
- 易联云k4php_易联云k4打印机重新绑定
- IDEA的一些炫酷的插件
- Android蓝牙协议栈学习