When talked about in terms of computations and processing, the words ‘concurrency’ and ‘parallelism’ seem quite similar. Well, NO!!
Just recently, I started learning GoLang. The Goroutines and Channels are excellent examples of differentiating the two categories of processing.
Quoting Sun’s Multithreaded Programming Guide, parallelism is a condition that arises when at least two threads are executing simultaneously where as concurrency is a condition that exists when at least two threads are making progress. Concurrency is a more generalised form of parallelism that can include time-slicing as a form of virtual parallelism.
Going by simpler words, when you divide an enormously sized computational task into smaller subtasks, and run them in parallel in modern day multicore CPU/GPU, parallelism occurs. On the other hand, concurrency happens when two tasks (not necessarily interdependent) start, run and complete in overlapping time periods. This does not mean that they run at exactly the same instant, i.e., concurrency can happen on a single processor system with effective time sharing. Importantly, a different task begins before the ongoing task completes.
It would not be wrong to say that the number of tasks actively being performed at any instance of time differentiates between the two models of multi-programming.
With respect to their implementations in GoLang, do refer to this talk by Rob Pike. He has beautifully explained the difference between the two.