什么是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--;

else

for (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 以及多线程的同步和互斥的内容,希望与大家一起学习一起进步,请大家继续关注我的博客,如果大家支持我的话,就顶我一下吧。

java race condition_java多线程(一)Race Condition现象及产生的原因相关推荐

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

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

  2. 多线程+Race Condition现象及产生的原因

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

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

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

  4. java的condition_java并发编程之Condition

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

  5. java 线程 condition_Java编程中实现Condition控制线程通信

    java中控制线程通信的方法 1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyall()控制线程通信.不灵活. 2.利用condition ...

  6. JAVA用多线程反而变慢了_Java中使用多线程不能明显提高程序效率的一些原因

    java中使用多线程不能明显提高程序效率的一些原因. 使用多个线程来处理多任务的时候,效率肯定是有提高的.但是必须要慎用,否则容易出现问题. 1.多线程主要是为了充分利用多核cpu,大内存这些资源. ...

  7. 100道Java并发和多线程面试题

    1.多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡.所谓"知其然知其所以然","会用"只是 ...

  8. 【Java/Python】多线程

    多线程编程基础 Java多线程 创建线程 继承Thread + 重写run(线程体) 通过Runnable接口实现多线程 静态代理设计模式 通过Calllable接口实现多线程 线程的状态和方法 停止 ...

  9. Java中控制多线程顺序执行

    Java中控制多线程顺序执行 一.概述 二.普通示例 三.控制示例 3.1.设置线程优先级 3.2.使用线程类的join() 3.2.1.在主线程join() 3.2.2.在子线程join() 3.3 ...

最新文章

  1. 记录-MySQL中的事件调度Event Scheduler
  2. java 双调旅行商 hamiltonian,双调欧几里得旅行商问题(TSP)
  3. ABAP常用Function
  4. 安装 SAP Cloud Application Programming SDK @sap/cds-dk 时报错以及解决方案
  5. 网络流与线性规划24题(写了一半,先鸽下了……)
  6. 爬虫-练习-爬取访问后可见的内容
  7. linux查看java编译版本,升级linux系统中的java版本到1.8
  8. python客户端与服务器端通信_python客户端与服务器端的通信
  9. java visibility_浅析Android中的visibility属性
  10. 【div+css】两个div,如何让内层的div在外层div中水平垂直居中
  11. 常用算法之-快速排序
  12. SQL server 2017安装教程
  13. PMP第6版 每日工具
  14. 数据链路层(一、二)——差错控制
  15. ANC主动降噪,FFT方案与FxLMS方案比较
  16. 2021大纲新增词汇
  17. 29岁的人生并不是那么平平淡淡_20190308
  18. speedoffice使用方法——Word如何设置段落背景颜色
  19. 【gitLab】gitLab新建项目步骤
  20. 推荐系统-协同过滤简单介绍

热门文章

  1. 一、PyTorch Cookbook(常用代码合集)
  2. python脚本——图片重命名、图片合成视频、faster-rcnn画P-R曲线
  3. 【Relax人生法则之躺平方法论】那些看似无足轻重 实则细思极恐的毒鸡汤
  4. 在CentOS 6.3 64bit上安装最新版tsar并监控ATS 5.3
  5. vim复制代码包含注释时格式会乱掉的解决办法
  6. leetcode-152 乘积最大子序列
  7. leetcode-21 合并两个有序链表
  8. 【案例】城市地址三级联动
  9. Nginx在windows下常用命令
  10. 分割catalina.out 每天生成一个文件