Javascript线程处理和竞争条件 [英] Javascript thread-handling and race-conditions

查看:141
本文介绍了Javascript线程处理和竞争条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下代码:

var shared = 100;
function workWithIt(){
    shared += 100;
}

setTimeout(workWithIt, 500);
setTimeout(workWithIt, 500);

理想情况下,这段代码应该将200加到变量 shared ,之后是300。

Ideally, this piece of code should add 200 to the variable shared, which is 300 afterwards.

但是,正如我从 c 所知,可以有一些含义,如果操作+ =被分成多个命令。

But, as I know from c, there can be some implications, if the operation += is split into multiple commands.

让我们说,这是函数的执行顺序:

Lets say, that this is the execution-order of the function:

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;                  |

在这种情况下,共享现在已经值200.

In this case, shared has now the value 200.

这可能发生在许多编程语言中,如c,c ++,java,c#,...... - 但是它也可以在Javascript中发生吗?

This can happen in many programming-languages like c, c++, java, c#, ... - but can it also happen in Javascript?

或者更一般地说:Javascript如何处理其线程,何时在线程之间切换,是否有内置方法,可用于处理竞争条件?

Or more generally speaking: How does Javascript handle its threads, when does it switch between threads, and are there built-in methods, that can be used for handling race-conditions?

推荐答案

JavaScript代码只有一个显式执行线程。您所描述的场景永远不会在JavaScript中发生。计时器回调只是另一种事件,所有事件都被序列化,以便由浏览器UI线程的同一核心事件循环顺序执行。

JavaScript code has a single explicit thread of execution. The scenario you've described will never take place in JavaScript. A timer callback is just another kind of event, and all events are serialized for sequential execution by the same core event loop of the browser UI thread.

因此,两个计时器事件不能同时处理,一个回调将一个接一个地发生。

Thus, two timer events cannot be processed concurrently, one callback will happen after another.

你还可以通过 Web Workers 在JavaScript中实现真正的并发性。但是,Web worker不能与另一个Web worker或主线程共享任何对象。相反,Web worker使用JSON序列化其状态对象,并使用 postMessage 交换消息。所以,你的情况仍然是不可能的。

You still can have real concurrency in JavaScript by means of Web Workers. However, a web worker cannot share any objects with another web worker or the main thread. Instead, web workers serialize their state objects with JSON, and exchange messages with postMessage. So, your scenario is still impossible.

然而,考虑另一种情况:

However, consider another case:

var shared = 100;

function workWithIt1(){
    shared += 100;
}

function workWithIt2(){
    shared = shared/2;
}

setTimeout(workWithIt1, 500);
setTimeout(workWithIt2, 500);

分享 150 或 100 ?它可能是 100 ,因为 workWithIt1 超时首先排队。但是,我不会依赖这个事实,因为两个计时器具有相同的超时值 500 ,并且计时器的实现可能是浏览器特定的。您可能希望避免代码中的副作用。

Will shared be 150 or 100, once both timeouts have been fired? It probably will be 100, because the workWithIt1 timeout was queued first. However, I would not rely upon this fact though, because both timers have the same timeout value of 500, and implementation of timers might be browser-specific. You may want to avoid side effects like that in your code.

这篇关于Javascript线程处理和竞争条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆