Read this first:
Eric Lippert has already written an excellent answer on Stack Overflow that should also answer your question: What is the difference between asynchronous programming and multithreading?
Your hunch is right; multi-threading wouldn't improve the performance aspects of IO-bound tasks.
What the Java author (as quoted by OP) says is, while it wouldn't improve performance, it reduces the complexity of your code.
Different goals, different conclusions.
My answer focuses on the use of terminology and the issue of confusion.
There are several levels of "can". The first one is the least generalisable and the third one is the most generalisable.
- That it is possible at all
- (i.e. without considering merits and efforts)
- That it is advantageous to do so in terms of a specific criteria
- (e.g. able to shorten the time to completion by leveraging unused CPU cores)
- That it is generally recommended for the given situations after a wide range of criteria have been considered
- (i.e. there is an accompanying list of criteria considered)
- (but, it also makes a lot of assumptions about "the general case / needs", which means someone with an unusual requirement may find it not applicable.)
When you mention "mutually-exclusive tasks", a better way to say that is tasks that can be independently executed, and does not obstruct and/or interfere (harm) each other when executed simultaneously (as in multiple CPU cores) or concurrently ("overlapped", or "asynchronously", or "task-switching").
It is always possible, and is usually advantageous, to have independently executable tasks executed over multiple CPUs. The exception to this rule is if the tasks are too small, then the overheads (mostly the wait time due to handing off tasks and results across CPUs) will ruin the savings.
Asynchronous is an adjective that roughly means punctuated. It means that a task is not continuously executing. It switches between executing and pausing (blocking). In general it is gradually progressing toward the goal (completion).
Asynchronous can refer to:
- The coding style,
- Syntactic and code-generation features provided by a programming language,
- The overall manner in which a higher-level task is executed, a fact which has to be judged subjectively.
When asynchronous programming is done on a programming language that does not provide the best syntactic sugar for it, the result is more complicated code which is harder to understand, maintain, and troubleshoot. Therefore, it comes with the advice (or, a break from the general advice) that, if the code complexity is too high, then it is advisable for one to abandon the asynchronous programming attempt and fall back to a synchronous coding style.
If the language provides very good syntactic sugar for it, then a lot of programming can be done in asynchronous programming style without suffering the code complexity.
Asynchronous code is not required to be single-threaded. In fact, on C# you can combine asynchronous programming and multithreading(*), as explained in Eric Lippert's answer (see top of answer for the link).
(*) It just creates a "how do I get back to the caller" / "code executing on the wrong thread" hell. For this reason it is recommended to have one "master thread" in charge of delegating tasks, and this "master thread" will implement an event loop, which is the mechanism through which it will receive procedure invocation, communication, and completion from other tasks or worker threads.
An architecture that is asynchronous and single-threaded may sometimes be chosen because of technical limitations of one or more libraries or frameworks it uses. For example, when programming on Windows, the GUI is usually single-threaded, which means it is not thread-safe to be invoked from a thread that is not the main-thread.
The word "I/O bound" is usually a misnomer. It basically means "tasks that take time to finish yet aren't CPU-bound."
As an example, a task that is sometimes said to be "I/O bound" involves just a little bit of data transmission. For example, data is being crunched on a remote server; the local computer's task is merely waiting for the remote server saying "done".