It may seem that there is no difference between concurrency and parallelism, but this is because you did not understand the essence of the matter. Let’s try to understand how they differ.
Concurrency is the execution of more than one task is being processed at the same time inside the application. An important detail is that tasks are not necessarily performed at the same time(but it’s possible), so they can be divided into smaller and alternating ones. In this case, threads can be physically executed simultaneously, but this is not necessary.
Tasks are not connected with each other. Therefore, it does not matter which of them will end earlier, and which later. Thus, concurrency can be realized in many ways — using green threads or processes or asynchronous operations that work on one CPU or something else.
Let’s draw an analogy: the secretary answering phone calls and sometimes checks the appointments. He needs to stop answering the phone in order to go to the desk and check for appointments, and then start answering and repeating this process until the end of the workday.
As you have noticed, concurrency is more connected with logistics. If it were not, then the secretary would wait until the time of the appointment and do necessary things and then go to the ringing phone.
Parallelism is the execution of tasks at the same time. The name itself implies that they are executed in parallel. Parallelism is one of the ways to implement concurrent execution by highlighting the abstraction of the worker thread or process. Also for parallelism to be true there have to be at least two CPU cores.
Back to the office: now we have two secretaries. One watches the phone and the other set up appointments. Work is divided because now there are two secretaries working in the office.
Parallelism is a subclass of concurrency: before performing several simultaneous tasks, you must first organize them correctly.