> For the complete documentation index, see [llms.txt](https://tingreavinash.gitbook.io/the-tech-toolbox/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tingreavinash.gitbook.io/the-tech-toolbox/notes/java-fundamentals/multithreading.md).

# Multithreading

#### Thread Synchronization

* `synchronized` keyword is used to achieve thread synchronization. It can be used with a method or a block of code.
* `wait()` and `notify()` methods are used to coordinate between threads. `wait()` method causes a thread to wait until another thread signals (by calling `notify()` method).
* `join()` method is used to wait for a thread to finish its execution before moving on to the next task.
* `volatile` keyword is used to make sure that the changes made to a variable by one thread are immediately visible to other threads.

#### Thread Pooling

* A thread pool is a group of pre-initialized threads that are ready to execute tasks.
* `ExecutorService` is an interface that represents an executor that can execute tasks asynchronously.
* `ThreadPoolExecutor` is a class that provides a thread pool implementation.
* `submit()` method is used to submit a task to the thread pool.
* `shutdown()` method is used to shutdown the thread pool after completing all the tasks.

#### Concurrent Collections

* Java provides thread-safe implementations of common collections in the `java.util.concurrent` package.
* Examples: `ConcurrentHashMap`, `ConcurrentLinkedQueue`, `CopyOnWriteArrayList`, etc.
* These collections are designed to be used in multi-threaded environments without the need for external synchronization.

#### Locks

* Java provides a `Lock` interface which can be used to achieve thread synchronization.
* `ReentrantLock` is a class that implements the `Lock` interface.
* `tryLock()` method is used to try to acquire the lock without waiting. It returns immediately with a boolean value indicating whether the lock was acquired or not.
* `lockInterruptibly()` method is used to acquire the lock while waiting for the lock to be released. If the thread is interrupted while waiting, an `InterruptedException` is thrown.

#### Atomic Variables

* Atomic variables are thread-safe variables that can be updated atomically.
* Java provides a set of classes in the `java.util.concurrent.atomic` package that implement atomic variables, such as `AtomicInteger`, `AtomicLong`, `AtomicBoolean`, etc.
* Atomic variables are designed to be used in multi-threaded environments without the need for external synchronization.

#### Thread Safety

* A class is thread-safe if it can be used by multiple threads at the same time without causing any issues.
* Immutable objects are inherently thread-safe because they cannot be modified after they are created.
* Synchronization is required to achieve thread safety for mutable objects.
* Locking can cause contention and degrade performance, so it should be used judiciously.
* Thread-safety can also be achieved using atomic variables and concurrent collections.

#### Executors

* Executors provide a simple way to create and manage threads.
* Executors provide a number of methods to create different types of thread pools, such as fixed thread pool, cached thread pool, and scheduled thread pool.
* Executors provide methods to execute tasks asynchronously and return the result in the form of a `Future` object.
* Executors can also be used to schedule tasks for execution at a later time.

#### Fork/Join Framework

* The fork/join framework is a concurrency mechanism introduced in Java 7.
* The framework is designed for recursive algorithms that can be broken down into smaller subtasks.
* The framework provides a `ForkJoinPool` class that manages a pool of worker threads and a `RecursiveTask` class that represents a task that can be broken down into smaller subtasks.
* The `invoke()` method of the `ForkJoinPool` class is used to submit a `RecursiveTask` to the pool for execution.

#### Thread Local Variables

* Thread local variables are variables that are local to a thread.
* Each thread has its own copy of the thread local variable.
* Thread local variables can be used to store thread-specific information, such as user preferences or database connections.
* Java provides a `ThreadLocal` class to create thread local variables.

#### Thread Deadlock

* Thread deadlock occurs when two or more threads are blocked, waiting for each other to release a resource.
* Deadlocks can occur when multiple threads acquire locks in a different order.
* To avoid deadlock, it is important to always acquire locks in the same order.
* Deadlocks can also occur when multiple threads wait indefinitely for a resource that is held by another thread.

#### Thread Starvation

* Thread starvation occurs when a thread is unable to acquire the resources it needs to continue executing.
* Starvation can occur when a thread is blocked waiting for a lock that is held by another thread.
* To avoid starvation, it is important to ensure that all threads have a fair chance of acquiring the resources they need.
* Java provides a `FairLock` class that ensures fairness in locking.
