What is context switch
Nowadays, we often use computer for multiple tasks at the same time even it just contains 1 CPU. You might think that each CPU is actually able to execute multiple tasks at the same time? That is totally wrong. Actually each CPU in the computer can only execute one task at the same time. The reason why we got the previous illusion is that CPU switch too fast for us to notice. And we call each of this short moment (ms level) Time Slice.
If we compare task to a car, then time slice is the fuel oil. Without fuel oil, car is not runnable. So is the relationship between time slice and thread.
And time slice will be allocated by CPU for executing a specific thread. No matter how short it is, once a thread owns a time slice lucky, this thread is runnable. And once time slice come to an end, CPU will store the progress of this thread, which we call context, and look for the next lucky thread, and load its context.
This is what we called context switch.
As the time slice is short enough, so our human being is not able to be aware of the switching, which make us feel like that our computer is running multiple tasks at the same time. But actually our CPU is working so hard to switch among multiple threads.
pros & cons
So now, it is obvious that the pros of context switch is that even 1 CPU can execute multiple task “at the same time”. Just like you hire a staff in a bank, while he is able to serve for multiple counter, how exciting it is.
But every coin has two sides.
The cons is also obvious, that is, you need to spend more effort on switching, which is not related to the real task. What`s worse, if the task/thread grows more and more, and it will consume all you memory for the context.
Solution
So how could we reducer the context switching? Below are 4 useful ways :
- Lockless : a lock is scrapped by multiple thread is one of the reason why we need context switch frequently. So we should try our best to avoid using lock during the multiple thread scenario. e.g.
- Use ConcurrentHashMap, whose segment lock will separate the id according to the hash algorithm, so that different thread will handle the data in different segment.
- CAS : Optimistic lock, no lock is required.
- With minimal thread : the more thread it is, the more thread is waiting.
- Coroutine : existed in framework, not supported by JDK.