This is my understanding of the difference between "Concurrency" and "Parallelism". I believe it's reasonably accurate - although feel free to discuss in the comments if you feel the distinction is different to my definition.
Effectively there is just "concurrency". Concurrency is the ability to handle multiple tasks/processes all running at the same time (rather than running tasks sequentially: one finishes, the next starts).
If there is only a single CPU available then concurrent processes won't perform as well as you might think because the CPU will be forced to do something called "task switching". Imagine you have two tasks (A and B) which are running concurrently; "task switching" breaks down to:
- CPU works on task A for a short (predetermined) amount of time
- If task A isn't complete by end of the set time frame then task B is started
- CPU works on task B (again only for the predetermined amount of time)
- If task B doesn't complete within the time frame then the CPU jumps back to work on task A
- ...and back and forth the single CPU goes until both task A and B are complete...
One way to improve "task switching" is to run tasks in parallel; but this requires multiple CPUs. Running tasks in parallel mean that both tasks A and B can genuinely run at the same time rather than one at a time (remember the default format of "task switching" isn't as slow as just running the task sequentially).
So it's best to think of Concurrency as the goal; and "task switching" and "parallelism" as specific implementations; the latter yielding the fastest results.
Here is an example implementation of "task switching" in JavaScript. JavaScript is a single threaded language and so cannot take advantage of true parallelism (hence the need for a function such as the below example demonstrates):