您提出的问题涉及到多线程并发执行时的竞态条件(Race Condition)问题。在并发编程中,如果两个或多个线程访问共享的数据,并且其中至少一个线程对数据进行写操作,就可能发生竞态条件。竞态条件可能导致意外的结果,因为线程执行的顺序不确定。
在您描述的情境中,两个线程执行 n = n + 1 操作,而且初始值是 n = 100。如果 Thread1 在执行 ILOAD(100) 后被操作系统中断,而此时 Thread2 开始执行,那么 Thread2 将读取 n 的值,这时 n 的值为 100。然后 Thread2 执行 n = n + 1 操作,将 n 的值增加到 101。接着,如果 Thread1 继续执行,它将读取之前保存的 n 的值(100)并执行 n = n + 1,将 n 的值增加到 101。
因此,在这种情况下,最终的结果是 101 而不是 102。这是由于并发执行导致的竞态条件,即多个线程同时访问并修改共享的数据,而执行顺序的不确定性导致了最终结果的不同。
在不同的执行时序下,最终结果可能是 101 或 102,这是由于并发执行的不确定性造成的。这种情况下,通常需要使用同步机制(例如锁)来确保在多线程环境下对共享数据的安全访问。
你是机器人吧
一个意思,
“ 比如 Thread1 执行完 ILOAD(100) 紧接着 Thread2 就开始执行 ”
不就是
“ Thread1 在 ILOAD(100) 执行后被中断 ”、 “ Thread2 就会读取成 100 而并不是 101 ”
这不是一个意思吗,在疑惑啥
Thread1读取数据后,还没改变数据,被中断,执行Thread2,然后结果不就如图
“被中断” 的意思是不是操作系统暂停执行当前线程, 转而去 执行其他线程了 ,然后过一会儿又回来执行当前线程 ?
这个从汇编看就能明白了,左值先取值100了,如图。然后其他线程不管怎么操作也改变不了左值已经是100这个值了,这个java线程栈有一定关系,栈之间相互独立
汇编有线程栈的概念吗 ? 可以推荐一本书吗 ?
这种教材还是别看了吧。。感觉不像是计算机专业人士编写的教程。
首先,需要分清楚这个n是从哪里来的。它是存储在哪里了。若以Java为例子,n若是存储在一个对象中,假设存在张三实例,那么张三放在了共享内存中,本质上线程1和线程2在执行n = n +1时,会把张三实例中的n拷贝给自己一份。因为线程有私有内存的,那么两个私有内存中都是101。
其次,执行顺序,假设是多核场景下,二者本质是并行执行的,那么两者其实没有任何关系。若是在单核CPU上运行,假设线程1执行结束之后,若没有把自己私有内存的101传给张三,那么线程2本质上还是自己的100,那么计算结果还是101。
最后,写入结果,若两者计算的都是101,那么写入的结果就是101,若存在不同,是否有相关的策略,是丢弃,还是先写入线程1,后写入线程2,本质就是谁覆盖谁的问题。
综上所述,n = n+1,本质在每个线程中经历了3个阶段,load,execute,write,而且三者的顺序是可以随机的。
load1,load2,execute1,execute2,write1,write2,只是其中一种。若添加了相关的关键字,例如将load, execute, write作为一组指令,要么全部成功,要么全部失败,不允许中断的场景下,这种组合还会变化。
这个从汇编看就能明白了,左值先取值100了,如图。然后其他线程不管怎么操作也改变不了左值已经是100这个值了,这个java线程栈有一定关系,栈之间相互独立
– 无敌旋律 1年前