Is JavaScript guaranteed to be single-threaded?

后端 未结 12 1661
遇见更好的自我
遇见更好的自我 2020-11-21 06:38

JavaScript is known to be single-threaded in all modern browser implementations, but is that specified in any standard or is it just by tradition? Is it totally safe to assu

相关标签:
12条回答
  • 2020-11-21 06:51

    No.

    I'm going against the crowd here, but bear with me. A single JS script is intended to be effectively single threaded, but this doesn't mean that it can't be interpreted differently.

    Let's say you have the following code...

    var list = [];
    for (var i = 0; i < 10000; i++) {
      list[i] = i * i;
    }
    

    This is written with the expectation that by the end of the loop, the list must have 10000 entries which are the index squared, but the VM could notice that each iteration of the loop does not affect the other, and reinterpret using two threads.

    First thread

    for (var i = 0; i < 5000; i++) {
      list[i] = i * i;
    }
    

    Second thread

    for (var i = 5000; i < 10000; i++) {
      list[i] = i * i;
    }
    

    I'm simplifying here, because JS arrays are more complicated then dumb chunks of memory, but if these two scripts are able to add entries to the array in a thread-safe way, then by the time both are done executing it'll have the same result as the single-threaded version.

    While I'm not aware of any VM detecting parallelizable code like this, it seems likely that it could come into existence in the future for JIT VMs, since it could offer more speed in some situations.

    Taking this concept further, it's possible that code could be annotated to let the VM know what to convert to multi-threaded code.

    // like "use strict" this enables certain features on compatible VMs.
    "use parallel";
    
    var list = [];
    
    // This string, which has no effect on incompatible VMs, enables threading on
    // this loop.
    "parallel for";
    for (var i = 0; i < 10000; i++) {
      list[i] = i * i;
    }
    

    Since Web Workers are coming to Javascript, it's unlikely that this... uglier system will ever come into existence, but I think it's safe to say Javascript is single-threaded by tradition.

    0 讨论(0)
  • 2020-11-21 06:51

    Well, Chrome is multiprocess, and I think every process deals with its own Javascript code, but as far as the code knows, it is "single-threaded".

    There is no support whatsoever in Javascript for multi-threading, at least not explicitly, so it does not make a difference.

    0 讨论(0)
  • 2020-11-21 06:52

    Yes, although Internet Explorer 9 will compile your Javascript on a separate thread in preparation for execution on the main thread. This doesn't change anything for you as a programmer, though.

    0 讨论(0)
  • 2020-11-21 06:53

    Try to nest two setTimeout functions within each other and they will behave multithreaded (ie; the outer timer won't wait for the inner one to complete before executing its function).

    0 讨论(0)
  • 2020-11-21 06:55

    @Bobince is providing a really opaque answer.

    Riffing off of Már Örlygsson's answer, Javascript is always single-threaded because of this simple fact: Everything in Javascript is executed along a single timeline.

    That is the strict definition of a single-threaded programming language.

    0 讨论(0)
  • 2020-11-21 06:56

    I've tried @bobince's example with a slight modifications:

    <html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <textarea id="log" rows="20" cols="40"></textarea>
        <br />
        <button id="act">Run</button>
        <script type="text/javascript">
            let l= document.getElementById('log');
            let b = document.getElementById('act');
            let s = 0;
    
            b.addEventListener('click', function() {
                l.value += 'click begin\n';
    
                s = 10;
                let s2 = s;
    
                alert('alert!');
    
                s = s + s2;
    
                l.value += 'click end\n';
                l.value += `result = ${s}, should be ${s2 + s2}\n`;
                l.value += '----------\n';
            });
    
            window.addEventListener('resize', function() {
                if (s === 10) {
                    s = 5;
                }
    
                l.value+= 'resize\n';
            });
        </script>
    </body>
    </html>
    

    So, when you press Run, close alert popup and do a "single thread", you should see something like this:

    click begin
    click end
    result = 20, should be 20
    

    But if you try to run this in Opera or Firefox stable on Windows and minimize/maximize window with alert popup on screen, then there will be something like this:

    click begin
    resize
    click end
    result = 15, should be 20
    

    I don't want to say, that this is "multithreading", but some piece of code had executed in a wrong time with me not expecting this, and now I have a corrupted state. And better to know about this behavior.

    0 讨论(0)
提交回复
热议问题