Understanding the jargon
Before we dive into the technicalities of threading and asynchronous operations, let's take a real-world example and build an analogy between multi-tasking in real life and parallel programming. Imagine that you are waiting in a queue in a restaurant to order food, and while waiting in the queue you reply to an email. Then, having ordered the food and while waiting for it to arrive, you reply to another email. In the restaurant, there are multiple counters where orders are being taken, and food is prepared by the chef while orders are being placed.
While you were waiting in line, you concurrently replied to an email. Similarly, while you were ordering, the restaurant was parallelly taking orders at many other counters. The chef is cooking parallelly while orders are being placed. Also, you were given a token to pick up your food from the pickup counter; however, depending upon the preparation time of your food, an order placed after yours may arrive...