Lock-Free Algorithms is one of the mechanisms in which thread-safe access to shared data is possible without the use of Synchronization primitives like mutexes. Multi-threaded applications have shared resources that may be passed among different threads used in the application.
- This poses the threat of race conditions and data races among the threads. In order to handle this situation, various techniques are used. One of the most common ways is to use synchronization and locks(also called monitors) which ensures thread safety. However, If excessive synchronization is used, the application performance would be hugely impacted along with the application getting more and more complex.
- We need to write applications that are thread-safe but at the same time, they should give us high performance and the benefit of concurrent execution. So, in order to minimize the usage of synchronization and reduce the complexity of locks, Java has a whole set of classes in the java.util.the concurrent package which provides many advanced operations that are lock-free and atomic.
- A large set of operations, in an application, can be performed without the need to synchronize most of the code. We need to understand what applies best in a situation and use the right tool for the job.
- We will see an example where first we display how synchronized locking is used in multi-threaded applications to achieve concurrency, and then we will see a solution providing a lock-free solution of the same problem.
The following example shows how synchronization and the locking mechanisms are used as a solution for concurrency.
Planting trees in progress... Concretization in progress... Number of trees in your area:: 10000
Now to convert the above example into a simple lock-free sample, we use the AtomicInteger class of Java which is part of the Concurrent package java.util.concurrent.atomic.AtomicInteger. It is a very useful class which can be easily used in concurrent applications as below :
Concretization in progress... Planting trees in process... Number of trees in your area::10000
Summary and Key Takeaways :
- The AtomicInteger class is a great tool that can be used in simple applications like concurrent counting and building simple readable code without the complexity of using a lock.
- AtomicInteger should be used only when atomic operations are needed. Also, the race condition can still exist between two separate atomic operations.
- The AtomicInteger class is on par and can sometimes be more efficient than a regular integer with a lock as protection.
- If an application is only using a single thread, the regular integer is preferred.
References: AtomicInteger class in Java
Attention reader! Don’t stop learning now. Get hold of all the important Java Foundation and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready.