Concurrency means doing things asynchronously – i.e. not waiting for one thing to finish to start other. Parallelism means doing things in parallel i.e. doing multiple operations at same instance of time. Don’t worry this post is not about Quantum theory of space and time, we are talking about software design concepts which have been around for quite some time now and people have written some very good articles about these.
I would be writing a series of posts around the two concepts because I want to write the content that helps in answering questions like:
• Can Concurrency help in a particular situation?
• I want to do a lot of things in parallel can I do them?
• What is required for Concurrency?
• What is required for Parallelism?
Why do I write another post about the subject if there are a lot of them – because they lack practical examples and they discuss more about the theory (and they lack very good diagrams). So without wasting any time and space let’s quickly jump over to the business.
Concurrency is a property of your program/code/software which means that you have optimized your code to not wait for operations which are non-deterministic in terms of time (simply put you don’t know how much time they are going to take to finish) and you have additional things to do along with your long running tasks. Let me make it very clear here that these additional tasks would not happen in parallel but the system (operating system) is going to make use of a technique known as time-slicing to allocate some of the processor time to both/all your asynchronous tasks. Concurrency helps you in making your programs better in terms of usability, user productivity and user experience. Before presenting any examples I would like to explain that Concurrency can help you with optimal usage of resources but this is not always the case and I am going to present examples where the resources (processor) are being optimized.
Let’s start with a basic example:
You have a single core, single processor machine and you want to write a word processing program which also does spelling and grammar check.
You might write a program that takes the user input from the user checks its spelling and whether it fits correctly (grammatically) in the input so far and if it’s okay then allows the user to enter next word. This would not be a very good approach from user productivity point of view because the user cannot do anything else while you are validating the inputs.
So you decide enough is enough let’s make it better and you modify the program to take all the user input in a single go and then check it in a single go. Well you have managed to get the user to do a lot of work continuously but they still need to wait while your code validates everything in the end. The user calls and says thanks for the changes now I can sit and enjoy while the software does the input validation and if my boss confronts me about sitting idle I can show them that things are happening and while they are happening I am supposed to wait.
So the solution to your problem lies in sharing (it is always good to share). What would you share? Share the processor. In a single core single processor environment a multi-tasking operating system has a feature known as time slicing which refers to switching execution of code at fast intervals to give an illusion of parallel execution of multiple code segments. How do you segregate code segments? There are constructs known as Threads which take code segments and execute them in their lifetime. The processor time is shared between these threads and the operating system does this switching at fast intervals. In our example we can have two threads, one which takes the user input and the other one which validates it. The operating system would do the time slicing between the two and your program would not require the use to wait because the program flow is not blocking the user input for the validation task to be finished. This is a program design property where you have designed your program in a way that the flow is not blocked between two related but independent tasks (user input and validation are related but are independent tasks).
We will discuss more about concurrency in the next post.