Concurrent execution of code ia bout two things: mutal exclusion and visibility of change.
- Mutual exclusion is about managing contented updtes to some resources.
- Visibiliyt of change is about controlling when such changes are made visible to other threads.
It is possible to avoid the need for mutal exclusion if you can eliminate the need for contented updates. If your algorithm can guarantee that any given resource is modified by only one thread then utal exclusion is unnecessary.
Read and write operations require that all changes are made visible to other threads.
The most costly operation in any concurrent environment is a contended write access.
Lock provide mutual exclusion and ensure that the visibility of change occurs in an ordered manner. Locks are incredibly expensive because they require arbitration when contended. This arbitration is achieved by a context switch to the OS kernerl which will suspend threads waiting on a lock until it’s released. During such a context switch , as well as releasing control to the OS which may decided to do other house-keeping tasks which it has control, execution context can lose previously cached data nad instrucionts. This can have a serious performance impact on modern CPU.