假设我有如下代码:
var shared = 100;
function workWithIt(){
shared += 100;
}
setTimeout(workWithIt, 500);
setTimeout(workWithIt, 500);
理想情况下,这段代码应该向变量添加 200shared
,之后就是 300。
但是,据我所知c
,如果 += 操作被分割成多个命令,可能会产生一些影响。
可以说,这是函数的执行顺序:
setTimeout() --> create Thread A
setTimeout() --> create Thread B
wait 500ms
**Thread A** | **Thread B**
--------------------------------+---------------------------------
var tmpA = shared; //100 |
| var tmpB = shared; //100
| tmpB = tmpB+100; //tmpB=200
| shared = tmpB;
tmpA = tmpA+100; //tmpA=200 |
shared = tmpA; |
在这种情况下,shared
现在值为 200。
这可能发生在许多编程语言中,如 c、c++、java、c# 等 - 但它也可能发生在 Javascript 中吗?
或者更一般地说:Javascript 如何处理其线程,何时在线程之间切换,以及是否有内置方法可用于处理竞争条件?
JavaScript 代码有一个显式的执行线程。你所描述的场景永远不会在 JavaScript 中发生。计时器回调只是另一种事件,所有事件都被序列化以便由浏览器 UI 线程的同一核心事件循环顺序执行。
因此,两个定时器事件不能同时处理,一个回调会接一个发生。
你仍然可以通过以下方式在 JavaScript 中实现真正的并发网络工作者。但是,Web Worker 无法与其他 Web Worker 或主线程共享任何对象。相反,Web Worker 使用 JSON 序列化其状态对象,并与postMessage
。所以,你的情况仍然是不可能的。
然而,考虑另一种情况:
var shared = 100;
function workWithIt1(){
shared += 100;
}
function workWithIt2(){
shared = shared/2;
}
setTimeout(workWithIt1, 500);
setTimeout(workWithIt2, 500);
Will shared
be 150
or 100
,一旦两个超时都被解雇?可能会是100
,因为workWithIt1
超时首先排队。但是,我不会依赖这个事实,因为两个计时器具有相同的超时值500
,并且计时器的实现可能是特定于浏览器的。您可能希望避免代码中出现类似的副作用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)