2

I was looking at the difference between JavaScript's single-threaded asynchronous processing and C#'s threaded approach to asynchronous processing as described here (Node.js vs Async/await in .net). It seems to me that 'asynchronous coding' could sum up the entirety of 'using threads' in a language like C# or Java. Is this the case?

My understanding of threads is code that executes on 2 separate processors at the same time, which as far as I can see involves:

  1. Firing off separate processes
  2. Asynchronous task processing, on a 'now' and 'later' basis
  3. Splitting tasks into partial tasks that operate on separate threads and then combining the results

It seems to me that point 2/3 are effectively handling asynchronous code in exactly the same logical manner that I would have with JavaScript. Though I (think I) understand that there are differences in terms of 'context' which would need to be added to a new thread? But it seems like async - await abstracts that if they don't...)

Aside from what I've mentioned, what is the difference from a JavaScript developer's point of view in terms of handling asynchronous code? From my inexperienced perspective with C#, it seems that asynchronous coding in JavaScript has many similarities to multi-threaded coding in C#.. Though with different use-cases... The one difference I can see is that code in JavaScript never executes simultaneously with other code, whereas in C# it might - is this where the idea of 'thread safety' comes from? i.e. a thread's state can't be altered by operations on another thread (I think)...

Is this correct? If not, what are the differences?

Community
  • 1
  • 1
Zach Smith
  • 8,458
  • 13
  • 59
  • 133
  • 3
    `My understanding of threads is code that executes on 2 separate processors at the same time` - this is incorrect. When you perform threading, be it c# or javascript, all you get is time splicing on the cpu, where the cpu will spends micro portions of time on each "thread". `Parallel.ForEach` in C# aims to put tasks on different processors. – Callum Linington Feb 15 '17 at 09:42
  • Even for `Parallel.ForEach`, MSDN says `iterations may run in parallel.` Does this mean that when you use threading in C# that you are actually saying to the computer `don't bother to try execute instructions in order, rather just execute as a efficiently as possible`? So in this case, is actual thread management completely taken care of by the CLR? – Zach Smith Feb 15 '17 at 09:53
  • Also: [There is no thread](http://blog.stephencleary.com/2013/11/there-is-no-thread.html) – Fildor Feb 15 '17 at 09:54
  • Yeah, so all thread management (or asynchronous requests) is controlled by the `ThreadPool` and abstractions around that. – Callum Linington Feb 15 '17 at 09:56
  • 1
    You can never achieve pure multi-threading in javascript because js will always run in single thread no matter what. And the event loop will make sure that all async calls are handled and executed without the code flow being disturbed . If you really want to compare multi-threading in other languages and JavaScript it would be worth comparing how spawn() / fork () and node clustering works. – damitj07 Feb 15 '17 at 10:12
  • @CallumLinington That's also not true. Using threads can get you one, the other, or a combination of both. – Servy Feb 15 '17 at 14:25

1 Answers1

4

Asynchrony and multithreading are both forms of concurrency:

  • Concurrency: doing more than one thing at a time.
  • Asynchrony: starting an operation and freeing up the current thread to do other things until that operation completes.
  • Parallelism / multithreading: using multiple threads to do multiple things at the same time.

I was looking at the difference between JavaScript's single-threaded asynchronous processing and C#'s threaded approach to asynchronous processing

I believe that my answer to that question misled you a bit. When I talk about "asynchronously multi-threaded", I mean that the asynchrony exists within a multi-threaded environment. I do not mean that the asynchrony is implemented using multi-threading.

JavaScript is (for now) locked into a single-threaded model (setting aside for the moment things like web workers which are kind of like threads). So, asynchrony is naturally done all on a single thread. Note that pure asynchrony does not require a thread for the asynchronous operation; e.g., when you do a web API call, there's no thread that has to sit, waiting for the response to come back. Node.js (and browser JavaScript for that matter) use similar techniques to the ones in my post There Is No Thread, plus a threadpool to wrap a small number of blocking APIs.

The important thing to note here is that asynchrony does not require a thread. It is a form of concurrency that can be threadless, in principle. On the server side, this permits a great degree of scalability.

JavaScript stops there, at least for now. Node.js scales quite well on a single thread (not counting the thread pool), since it enforces asynchrony. ASP.NET takes a different approach: asynchrony has historically been a pain to use, so ASP.NET multi-threads first and then allows asynchronous or synchronous code; modern services can use asynchrony in that multi-threaded environment for even more scalability.

It seems to me that 'asynchronous coding' could sum up the entirety of 'using threads' in a language like C# or Java. Is this the case?

No. There is one class of work that does not fit well with asynchrony: CPU-bound algorithms. In this case, your "work" has actual CPU code that it must run on an actual CPU. If you're doing something like that, you need real threads. In this case, you'd want parallelism rather than asynchrony. Parallelism is slowly coming to JavaScript, but they're starting at a very low level and it will be quite some time before high-level parallelism is a viable option.

Side note: C# code can choose to run asynchronous code all on one thread. In fact, this is the default environment for client-side apps (UI apps on desktop/mobile). The multi-threaded asynchronous environment is generally only used on the server, e.g., ASP.NET.

My understanding of threads is code that executes on 2 separate processors at the same time

It can. This depends on the cores in the machine and what else the machine is doing. .NET provides high-level parallelism abstractions for splitting up your work into chunks and distributing those among threads, where the threads run on cores, and doing all of this in a highly intelligent and adaptive manner. JavaScript currently has no parallelism support like this.

It seems to me that point 2/3 are effectively handling asynchronous code in exactly the same logical manner that I would have with JavaScript.

Yes, except for the fact that JavaScript asynchronous code cannot be CPU-bound. E.g., you could use parallelism on .NET to calculate a fractal; you can't do this using only async/await (regardless of language).

From my inexperienced perspective with C#, it seems that asynchronous coding in JavaScript has many similarities to multi-threaded coding in C#.

From a high-level perspective, yes: they're both forms of concurrency.

If you mean that async/await in JavaScript is similar to async/await in C#, then yes, they're practically the same thing. async/await are used to implement asynchrony in both languages.

Though with different use-cases... The one difference I can see is that code in JavaScript never executes simultaneously with other code, whereas in C# it might - is this where the idea of 'thread safety' comes from? i.e. a thread's state can't be altered by operations on another thread (I think)...

Yes, any time you have multi-threading, you need to ensure thread safety. So, any kind of parallel code in C# needs to ensure it is threadsafe. Asynchronous code in a multi-threaded environment can also run into thread safety issues, but that's more rare (most asynchronous code is serial, which can have no thread safety issues).

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Asynchrony and multithreading can *potentially* create concurrency. Neither *necessarily* creates concurrency. "multithreading" doesn't necessarily mean doing multiple things at the same time, it *just* means using multiple threads. Parallelism also isn't a synonym for multithreading, it's a synonym for concurrency. – Servy Feb 15 '17 at 14:28
  • 2
    @Servy: Parallelism and concurrency are not synonyms. – Stephen Cleary Feb 15 '17 at 14:37
  • Parallelism is doing multiple things at the same time. Concurrency is doing multiple things at the same time. You can achieve parallelism though a number of means, threads is one of them, asynchrony is another. – Servy Feb 15 '17 at 14:38
  • @Servy: We've been through this before. Your taxonomy is insufficiently nuanced for general use. – Stephen Cleary Feb 15 '17 at 14:56
  • 2
    Not at all. In my taxonomy, parallelism is a subset of multithreading, not a synonym. I grouped them together here because the op is familiar with neither. – Stephen Cleary Feb 15 '17 at 15:00
  • 2
    @Servy Whatevs, I'm out. – Stephen Cleary Feb 15 '17 at 15:13
  • Thank you for the answer. It's very helpful. It's also helpful knowing that there are differences in opinion on terminology! – Zach Smith Feb 15 '17 at 22:51
  • Where can I find more information on this: `Parallelism is slowly coming to JavaScript, but they're starting at a very low level and it will be quite some time before high-level parallelism is a viable option.` – Zach Smith Feb 15 '17 at 22:53
  • @ZachSmith: [2ality](http://www.2ality.com/2017/01/shared-array-buffer.html) is a great resource to follow JS evolution. – Stephen Cleary Feb 16 '17 at 02:20
  • @StephenCleary this was so helpful to me. – Neo Nov 29 '17 at 15:15
  • @StephenCleary "JavaScript is (for now) locked into a single-threaded model (setting aside for the moment things like web workers which are kind of like threads). " Workers *are* threads! UX interaction has to be single-threaded but Service Worker and Web worker code can and do execute in parallel with the Main-Thread/Event-loop. – McMurphy Dec 01 '17 at 03:06