Multithreading
Thread Synchronization
synchronized
keyword is used to achieve thread synchronization. It can be used with a method or a block of code.wait()
andnotify()
methods are used to coordinate between threads.wait()
method causes a thread to wait until another thread signals (by callingnotify()
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 theLock
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, anInterruptedException
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 asAtomicInteger
,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 aRecursiveTask
class that represents a task that can be broken down into smaller subtasks.The
invoke()
method of theForkJoinPool
class is used to submit aRecursiveTask
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.
Last updated