Are Mutexes needed in javascript?

JavascriptMultithreadingMutex

Javascript Problem Overview


I have seen this link: Implementing Mutual Exclusion in JavaScript. On the other hand, I have read that there are no threads in javascript, but what exactly does that mean?

When events occur, where in the code can they interrupt?

And if there are no threads in JS, do I need to use mutexes in JS or not?

Specifically, I am wondering about the effects of using functions called by setTimeout() and XmlHttpRequest's onreadystatechange on globally accessible variables.

Javascript Solutions


Solution 1 - Javascript

Javascript is defined as a reentrant language which means there is no threading exposed to the user, there may be threads in the implementation. Functions like setTimeout() and asynchronous callbacks need to wait for the script engine to sleep before they're able to run.

That means that everything that happens in an event must be finished before the next event will be processed.

That being said, you may need a mutex if your code does something where it expects a value not to change between when the asynchronous event was fired and when the callback was called.

For example if you have a data structure where you click one button and it sends an XmlHttpRequest which calls a callback the changes the data structure in a destructive way, and you have another button that changes the same data structure directly, between when the event was fired and when the call back was executed the user could have clicked and updated the data structure before the callback which could then lose the value.

While you could create a race condition like that it's very easy to prevent that in your code since each function will be atomic. It would be a lot of work and take some odd coding patterns to create the race condition in fact.

Solution 2 - Javascript

The answers to this question are a bit outdated though correct at the time they were given. And still correct if looking at a client-side javascript application that does NOT use webworkers.

Articles on web-workers:
multithreading in javascript using webworkers
Mozilla on webworkers

This clearly shows that javascript via web-workers has multithreading capabilities. As concerning to the question are mutexes needed in javascript? I am unsure of this. But this stackoverflow post seems relevant:
Mutual Exclusion for N Asynchronous Threads

Solution 3 - Javascript

As @william points out,

> you may need a mutex if your code does something where it expects a > value not to change between when the asynchronous event was fired and > when the callback was called.

This can be generalised further - if your code does something where it expects exclusive control of a resource until an asynchronous request resolves, you may need a mutex.

A simple example is where you have a button that fires an ajax call to create a record in the back end. You might need a bit of code to protect you from trigger happy users clicking away and thereby creating multiple records. there are a number of approaches to this problem (e.g. disable the button, enable on ajax success). You could also use a simple lock:

var save_lock = false;
$('#save_button').click(function(){
	if(!save_lock){
		//lock
		save_lock=true;
		$.ajax({
			success:function()
				//unlock
				save_lock = false;	
			}
		});
	}
}

I'm not sure if that's the best approach and I would be interested to see how others handle mutual exclusion in javascript, but as far as i'm aware that's a simple mutex and it is handy.

Solution 4 - Javascript

Yes, mutexes can be required in Javascript when accessing resources that are shared between tabs/windows, like localStorage.

For example, if a user has two tabs open, simple code like the following is unsafe:

function appendToList(item) {
    var list = localStorage["myKey"];
    if (list) {
        list += "," + item;
    }
    else {
        list = item;
    }
    localStorage["myKey"] = list;
}

Between the time that the localStorage item is 'got' and 'set', another tab could have modified the value. It's generally unlikely, but possible - you'd need to judge for yourself the likelihood and risk associated with any contention in your particular circumstances.

See the following articles for a more detail:

Solution 5 - Javascript

JavaScript is single threaded... though Chrome may be a new beast (I think it is also single threaded, but each tab has it's own JavaScript thread... I haven't looked into it in detail, so don't quote me there).

However, one thing you DO need to worry about is how your JavaScript will handle multiple ajax requests coming back in not the same order you send them. So, all you really need to worry about is make sure your ajax calls are handled in a way that they won't step on eachother's feet if the results come back in a different order than you sent them.

This goes for timeouts too...

When JavaScript grows multithreading, then maybe worry about mutexes and the like....

Solution 6 - Javascript

JavaScript, the language, can be as multithreaded as you want, but browser embeddings of the javascript engine only runs one callback (onload, onfocus, <script>, etc...) at a time (per tab, presumably). William's suggestion of using a Mutex for changes between registering and receiving a callback should not be taken too literally because of this, as you wouldn't want to block in the intervening callback since the callback that will unlock it will be blocked behind the current callback! (Wow, English sucks for talking about threading.) In this case, you probably want to do something along the lines of redispatching the current event if a flag is set, either literally or with the likes of setTimeout().

If you are using a different embedding of JS, and that executes multiple threads at once, it can get a bit more dicey, but due to the way JS can use callbacks so easily and locks objects on property access explicit locking is not nearly as necessary. However, I would be surprised if an embedding designed for general code (eg, game scripting) that used multi threading didn't also give some explicit locking primitives as well.

Sorry for the wall of text!

Solution 7 - Javascript

Events are signaled, but JavaScript execution is still single-threaded.

My understanding is that when event is signaled the engine stops what it is executing at the moment to run event handler. After the handler is finished, script execution is resumed. If event handler changed some shared variables then resumed code will see these changes appearing "out of the blue".

If you want to "protect" shared data, simple boolean flag should be sufficient.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOveshView Question on Stackoverflow
Solution 1 - JavascriptWilliamView Answer on Stackoverflow
Solution 2 - JavascriptgorillatronView Answer on Stackoverflow
Solution 3 - JavascriptalzclarkeView Answer on Stackoverflow
Solution 4 - JavascriptdecatesView Answer on Stackoverflow
Solution 5 - JavascriptMike StoneView Answer on Stackoverflow
Solution 6 - JavascriptSimon BuchanView Answer on Stackoverflow
Solution 7 - JavascriptConstantinView Answer on Stackoverflow