# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tingreavinash.gitbook.io/the-tech-toolbox/notes/java-fundamentals/multithreading.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
