Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我们可以在单线程脚本语言中使用竞争条件吗?_Javascript_Multithreading_Concurrency_Race Condition - Fatal编程技术网

Javascript 我们可以在单线程脚本语言中使用竞争条件吗?

Javascript 我们可以在单线程脚本语言中使用竞争条件吗?,javascript,multithreading,concurrency,race-condition,Javascript,Multithreading,Concurrency,Race Condition,我经常读到,在javascript中,您不必担心竞争条件,因为它是单线程的。但我相信这是因为事件循环的本质。如果Javascrit没有“”特性,它仍然可能存在并发性问题 让我们考虑这个代码片段: 1 var pending = []; 2 document.getElementById("submitBtn").addEventListener(function() { 3 var val = document.getElementById("textBox").value; 4

我经常读到,在javascript中,您不必担心竞争条件,因为它是单线程的。但我相信这是因为事件循环的本质。如果Javascrit没有“”特性,它仍然可能存在并发性问题

让我们考虑这个代码片段:

1  var pending = [];

2  document.getElementById("submitBtn").addEventListener(function() {
3      var val = document.getElementById("textBox").value;
4      pending.push(val);
5  });

6  setInterval(function() {
7     processValues(pending);
8     pending = [];
9  }, 3000);
Asume说javascript“”中没有这样的功能,任何事件都可以被抢先运行另一个事件/代码

现在假设执行第7行,突然事件被抢占,以处理第3行的事件。执行第3行和第4行后,从第8行恢复上一个事件。现在,当执行第8行时,
pending
中新添加的值将丢失,因为它既不由
processValues
函数处理,也不在
pending
数组中

即使是单线程,也会发生争用条件。所以,说javascript没有竞争条件是不对的,因为它是单线程的?具体来说,这是因为javascript的特性

编辑


显然,javascript中可能存在竞争条件。我所指的是某种类型的竞争条件,它不会因为javascript的单线程(或?)特性而发生。例如,我上面描述的一个。

是的,我们在单线程JavaScript中有竞争条件。只是数量不如多线程代码(前提是您不使用
alert
confirm
,详见下文)

您首先说“假设没有跑步到完成的功能”,然后描述了一个依赖于此的比赛条件。但这种竞争条件不可能发生,因为正如您所说,JavaScript已经运行到了完成阶段

虽然在JavaScript中确实存在一类我们不必担心的竞争条件,但我们仍然需要担心很多。例如,异步代码总是有可能出现竞争条件。(这就是ajax调用、来自web工作人员的消息等)

下面是一个常见的错误示例,这是一个真实的比赛条件:

var img = document.createElement('img');
img.src = "kittens.png";
img.onload = function() {
    console.log("It loaded");
};
document.body.appendChild(img);
那很安全,对吗错误。仅仅因为JavaScript是单线程运行的,并不意味着浏览器是单线程的。当浏览器看到
img.src=“kittens.png”
,如果映像在缓存中,则它完全有权在该
img
上触发
load
事件:该事件将查找任何处理程序,而不会找到任何处理程序,因此在当前代码完成后不会将任何回调排队以运行-并且我们没有看到“it loaded”消息

虽然这是一个基于浏览器的示例,但它是一个一般原则的示例:仅仅因为主机环境运行一个主JavaScript线程,这并不意味着主机环境不是多线程的,而且多线程可能会对我们的单线程代码产生影响

这只是一个例子。但事实上,我们是安全的。例如,如果我们更改上述代码:

var img = document.createElement('img');
img.onload = function() {
    console.log("It loaded");
};
img.src = "kittens.png";
document.body.appendChild(img);
doSomethingElse();

…我们知道
doSomethingElse
将在
运行之前被调用,在
警报
确认
函数周围的某些浏览器(我在看你,Mozilla)上会出现一些不愉快的边缘情况。(TL;DR-至少某些版本的Firefox会在等待用户解除
警报时触发ajax完成回调)

你在哪里读到的?竞态条件在异步代码中很常见。竞态条件可能存在于javascript、WebSocket等的异步部分。对此,如果您感到好奇,我们已经提供了一个深思熟虑的答案:@Jivings@adeneo检查问题的答案@brianvaughn。答案是“竞态条件只能发生在两个或多个线程之间”对于脚本语言,我认为这是不正确的。这把我弄糊涂了。回答得好。尽管我认为问题在于javascript并不是真正的单线程。如果你看到一个简单的Java程序没有启动任何线程或任何东西,也没有异步方法(实际上异步意味着多线程),那么就不可能创建竞争条件,对吗?@maraca:好吧,JavaScript语言对线程是完全沉默的。唯一的线程保证是由主机提供的。web浏览器上的JavaScript可以访问单个UI线程和X个web工作人员。忽略web workers,基于浏览器的JavaScript实际上是单线程的,这就排除了我在回答末尾提到的问题,web workers被非常智能地设计为使用消息事件模型和worker隔离来避免破坏这一点。类似地,NodeJS上的JavaScript由NodeJS保证一个线程。JVM(Rhino,Nashorn)上的JavaScript不是。@t.JCrowder是的,这正是我的观点,你不能将这一点应用于JavaScript,但可能适用于其他语言。@t.J.Crowder你是对的,JavaScript中可能会出现竞争条件。请参阅我的最新问题。