Java Multithreading: quick revision, 14 bites

All 14 revision bites from this kit, free and with no sign-up.

What is Multithreading?

Run multiple tasks simultaneously in Java.

**Multithreading** in Java is a process of executing multiple threads simultaneously to maximize CPU utilization. A **thread** is a lightweight sub-process, and each thread runs independently but shares memory. Java provides built-in support for multithreading via the `Thread` class and `Runnable` interface.

Takeaway. Multithreading allows concurrent execution of multiple threads to improve performance and responsiveness.

Thread and Process

Know the difference between thread and process.

A **process** is an independent program in execution with its own memory space. A **thread** is a smaller unit of a process that can run concurrently. Multiple threads of the same process share the process's memory and resources, making communication between threads faster than between processes.

Takeaway. Threads are lightweight and share memory, unlike processes which are independent and heavier.

Thread Lifecycle

Threads move through several states.

A Java thread can be in one of the following states: **New**, **Runnable**, **Blocked**, **Waiting**, **Timed Waiting**, or **Terminated**. The lifecycle starts when a thread is created and ends when it finishes execution. The `Thread.State` enum defines these states.

Takeaway. Understanding the thread lifecycle helps in debugging and managing thread behavior.

Creating Threads with Thread Class

Extend Thread to create a thread.

To create a thread by extending the `Thread` class, override the `run()` method. Then create an instance of the subclass and call `start()` to begin execution. The `start()` method internally calls `run()` on a new thread.

Takeaway. Extending `Thread` and overriding `run()` is a simple way to create a thread.

Creating Threads with Runnable Interface

Implement Runnable for flexibility.

Implement the `Runnable` interface and pass the instance to a `Thread` constructor. This is preferred when your class already extends another class, as Java supports single inheritance. The `run()` method must be implemented.

Takeaway. Implementing `Runnable` is more flexible and avoids inheritance limitations.

Thread Scheduler and Priorities

Scheduler decides thread execution order.

The **thread scheduler** in Java determines which thread runs and for how long. Each thread has a **priority** (from 1 to 10), with higher priority threads generally getting more CPU time. The `setPriority(int)` method sets priority, and `getPriority()` retrieves it.

Takeaway. Thread priorities influence scheduling but do not guarantee execution order.

Calling run() Instead of start()

Avoid this classic mistake.

A common mistake is calling `run()` directly instead of `start()`. Calling `run()` executes the method in the current thread, not in a new thread. Always call `start()` to create a new thread and execute `run()` concurrently.

Takeaway. Always use `start()` to begin a new thread; `run()` just calls the method in the same thread.

Synchronization in Java

Prevent thread interference with locks.

**Synchronization** is a mechanism that ensures only one thread can access a shared resource at a time. It prevents **race conditions** and data inconsistency. Use the `synchronized` keyword on methods or blocks to acquire a lock on the object.

Takeaway. Synchronization prevents data corruption when multiple threads access shared resources.

Inter-thread Communication

Threads can talk to each other.

Java provides `wait()`, `notify()`, and `notifyAll()` methods for **inter-thread communication**. These methods are called on the object whose lock is held. `wait()` makes the current thread release the lock and wait, while `notify()` wakes up one waiting thread.

Takeaway. Use wait/notify for efficient coordination between threads.

Deadlock in Multithreading

Avoid threads waiting forever.

**Deadlock** occurs when two or more threads are blocked forever, each waiting for a resource held by another. This can happen when using nested synchronized blocks with multiple locks. Deadlock is a serious issue that can freeze the application.

Takeaway. Deadlock is a critical failure; use consistent lock ordering to prevent it.

Real-world Use of Multithreading

Where is multithreading used?

Multithreading is used in **web servers** to handle multiple client requests concurrently, in **GUI applications** to keep the interface responsive, and in **background tasks** like file downloading or data processing. It improves performance and user experience.

Takeaway. Multithreading is essential for responsive and high-performance applications.

Key Methods for Thread Control

Remember these important methods.

Takeaway. Knowing these methods helps in managing thread execution effectively.

Remembering Thread States

Use the acronym NRBWT.

Remember the thread states with **NRBWT**: New, Runnable, Blocked, Waiting, Timed Waiting. The final state is Terminated. This helps recall the lifecycle in order.

Takeaway. NRBWT is a quick way to remember the main thread states.

Thread Safety and Volatile

Volatile ensures visibility across threads.

The `volatile` keyword in Java ensures that changes to a variable are immediately visible to all threads. It prevents caching of the variable in thread-local memory, which can cause inconsistency. However, it does not guarantee atomicity.

Takeaway. `volatile` ensures visibility but not atomicity; use it for simple flags.

Make your own

Your notes can be a kit like these

Every kit here was made from real study material. Point Veda at a chapter, a PDF, a photo or a link and get notes, flashcards, practice MCQs, games and a scored test — free, in 42 languages.

  • Chapter notes
  • Flashcards
  • Practice MCQs
  • Scored tests
  • Exam prep

Get Veda free See what students get

Free to start · No ads · Works in 42 languages