Javascript stream processing and race conditions

Allows me to use the following code:

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

Ideally, this piece of code should add 200 to the shared variable, which after that will be 300.

But, as I know from c , there may be some consequences if the operation + = is divided into several commands.

Suppose this is an executable function order:

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

In this case, shared now has a value of 200.

This can happen in many programming languages, such as c, C ++, java, C #, ... - but can it happen in Javascript too?

Or, more generally, how does Javascript handle its threads when it switches between threads, and are there any built-in methods that can be used to handle race conditions?

+4
javascript multithreading synchronization thread-safety race-condition
Jan 30 '14 at 21:02
source share
2 answers

JavaScript code has one explicit thread of execution. The script you described will never take place in JavaScript. A timer callback is another type of event, and all events are serialized for sequential execution by the same cycle of events in the browser user interface stream.

Thus, two timer events cannot be processed simultaneously; one callback will occur after another.

You can still have real concurrency in JavaScript using Production Websites . However, the web worker cannot share any objects with another web worker or main thread. Instead, web executors serialize their state objects using JSON and exchange messages using postMessage . So your script is still not possible.

However, consider another case:

 var shared = 100; function workWithIt1(){ shared += 100; } function workWithIt2(){ shared = shared/2; } setTimeout(workWithIt1, 500); setTimeout(workWithIt2, 500); 

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

+6
Jan 30 '14 at 22:10
source share

AFAIK, in JS there is no multithreading. I modified your example a bit to understand what you mean.

 var shared = 100; function workWithIt(a){ shared += a||100; console.log(shared); } setTimeout(function(){workWithIt(5);}, 500); setTimeout(function(){workWithIt(10);}, 500); console.log(shared); 

With this code, the result is always (in my testing):

 100 105 110 

This indicates that there is no chaotic or random or even interesting process. There are certain possibilities for creating racing conditions with JS in the browser, but your synchronization example is not the same. Racing only requires a breakdown in the predictability of the execution order. Perhaps if you change the delay from 500 to Math.floor(500 * Math.random()) , you will have a racing mode.

+1
Jan 30 '14 at 21:25
source share



All Articles