What are important Threading Techniques & Concepts in Java
In this tutorial we are going to learn about important Threading Techniques & Concepts in Java.
The usual disclaimer: concurrent programming, in any language, using any abstraction level, is hard and complicated and has many risks. Take into consideration:
- Concurrent programming complicates any application by magnitude
- Unit-testing critical sections is hard, and sometimes impossible
- Reproducing bugs originating in concurrent code is very hard and much dependent on architecture, OS flavor, version, etc…
Java has gone a long way in making concurrent programming as easy as possible for developers. For most cases, you will see that java.util.concurrent has most of the abstractions you will need:
- Runnable interface and Thread object you can extend. Just throw in your code and you have a thread ready to run
- A nice set of Executors: constant pool, dynamic pool, scheduled, or whatever. Just throw a Runnable at it and it does the rest.
- Semaphores and locks of all sorts relieve you of needing to implement common locking techniques.
- A built-in wait() and notify() API for all objects.
Uses: The only thing left for you, as the software engineer, is to ensure you are writing correct code. Meaning you should be aware of the dangerous situations you might be exposing yourself to:
- Deadlock - a situation in which two or more threads are waiting on unordered resources, rendering an infinite waiting loop.
- Livelock - two or more threads which politely try to give way to the other on a shared resource but end up not taking it (consider two people in a corridor walking up to each other and constantly moving together from side to side)
- Starvation - a single thread taking up most or all of a single shared resource, thus depriving other threads from access to it.
- Use threads only when concurrency will directly improve your applications behavior.
- If you are waiting on an IO/network/hardware-bound resource, DO spawn a thread on it so you can continue doing other stuff.
- If you are just trying to elegantly split CPU-bound computations, DO NOT use threads. You just might end up worsening your performance.
- If you do use threads, make sure you have thoroughly contemplated the risks, and triple-checked you did not miss any exceptional situations.