Hacker News new | ask | show | jobs
by livre 1848 days ago
Saying that JavaScript is single threaded isn't accurate anymore. Even the article we just read mentions that you can run multiple threads with WebWorkers. The problem with JavaScript is that the main thread may* block the UI.

* Why may? The older APIs such as document.write and synchronous XHR do but modern browsers already warn against that. And the modern APIs don't block the UI because they are asynchronous and work with callbacks or promises. Bad JavaScript code can make the UI sluggish though, people should be performing complex tasks on a WebWorker but that's not as easy or as obvious as the default of performing them on the UI thread. The same problems can happen in native Windows programming for the same reason, the UI thread being the main thread. This is a bad design decision from decades ago that will likely haunt us for many more decades in the desktop OS and on the web.

1 comments

> Saying that JavaScript is single threaded isn't accurate anymore. Even the article we just read mentions that you can run multiple threads with WebWorkers

This doesn't make Javascript multithreaded. It means you run single-threaded programs in separate containers and pass messages between them.

Who cares about the details - you can create multiple workers, running on different threads. That’s multithreading.
> Who cares about the details

People who actually care about multithreading

> you can create multiple workers, running on different threads. That’s multithreading.

It's not.

If you mean multithreaded as running separate OS threads I've got to agree with you but the definition of thread isn't limited to just that. I don't know about the internals of web browsers or whether they use OS threads or green threads or a combination of both for web workers but they are threads and that's how the MDN calls them too: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers...
> and that's how the MDN calls them too

These are the browser's background threads, maybe. They don't make Javascript multithreaded or even Javascript runtimes multithreaded.

More here: https://news.ycombinator.com/item?id=27397555

I'm not sure I get your point. It's more or less what I said, it isn't using real OS threads but it is doing something similar to green threads. It isn't true multithreading in the sense that it doesn't spawn an OS thread but it spawns lightweight (or green or simulated) threads with their own VM.
> It's more or less what I said, it isn't using real OS threads but it is doing something similar to green threads.

It's not even green threads.

Also, literally on the page you linked:

=== start quote ===

The Worker interface spawns real OS-level threads,

=== end quote ===

[1]

> it doesn't spawn an OS thread but it spawns lightweight (or green or simulated) threads with their own VM.

It spawns an isolated process. Javascript as a language and its runtime cannot support threads. To do "threads" they basically initialise a new instance of JS runtime.

This is not "threading" by any definition. MDN page may call that for the sake of people who end up using it, but these are not:

- threads

- green threads

- lightweight

If in doubt, you could try and find any implementation of a thread or a worker in the JS VM: https://github.com/mozilla/gecko-dev/tree/master/js/src/vm

It's not there, because workers are implemented at the DOM level, in the browser: https://github.com/mozilla/gecko-dev/tree/master/dom/workers

It's an outside implementation, running processes inside the host, and letting processes communicate using memory-mapped values. 20 years ago no one in their right mind would call this "multithreading in language X". It was "app 1 written in any language is communicating with app 2 written in any language via memory-mapped files". Now people who've never seen anything outside web development call it multithreading.

[1] Fun trivia: original implementation literally used a runtime per worker: https://blog.mozilla.org/luke/2012/01/24/jsruntime-is-now-of... It still uses a CycleCollectedJSRuntime per worker, but I'm too lazy to dig through source code for further details.

> It spawns an isolated process. Javascript as a language and its runtime cannot support threads. To do "threads" they basically initialise a new instance of JS runtime.

Sometimes I need an answer as blunt and direct as that one to understand something, thanks.

Does the presence of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... fit your definition of multithreading?
Literally on that page, emphasis mine:

=== start quote ===

To share memory using SharedArrayBuffer objects from one agent in the cluster to another (an agent is either the web page’s main program or one of its web workers), postMessage and structured cloning is used.

=== end quote ===

And, of course, they are almost exclusively used with Web Workers because it makes zero sense to use them in the context of a single page. They are basically memory-mapped files, but for the browser, and their presence doesn't make Javascript and its runtime multithreaded.

There's also a good overview on the history of concurrency and parallelism in JS here: https://exploringjs.com/es2016-es2017/ch_shared-array-buffer...

IIRC Javascript can't even be made multithreaded because there are places in the spec that can't work in a multithreaded environment, but don't quote me on that.

I think you are missing the key point there.

> However, the shared data block referenced by the two SharedArrayBuffer objects is the same data block, and a side effect to the block in one agent will eventually become visible in the other agent.

This gives you shared memory between two threads. Sure the entire address space isn't shared but I find it hard to deny that this is threading.

> This gives you shared memory between two threads.

This is the key point you're missing. It's not "two threads". It's to different isolated tasks/processes.

Shared array buffers are quite literally what memory-mapped files have been used for over 40 years [1]

=== start quote ===

Another common use for memory-mapped files is to share memory between multiple processes. In modern protected mode operating systems, processes are generally not permitted to access memory space that is allocated for use by another process... There are a number of techniques available to safely share memory, and memory-mapped file I/O is one of the most popular. Two or more applications can simultaneously map a single physical file into memory and access this memory.

=== end quote ===

That's all there is: two separate, isolated processes accessing the same memory. This doesn't make Javascript multithreaded in any way, shape, or form. Browsers give you a rather awkward way to run a separate tasks in Javascript and give you message-passing and shared memory as a way to communicate between them.

Had browsers been able to run other languages than Javascript, you would be able to run one worker in Javascript, and another in SadlyNonExistentScript, and literally nothing would change: you would still have the same postMessage and SharedArrayBuffer as APIs provided by the host.

[1] https://en.wikipedia.org/wiki/Memory-mapped_file