Posts

Showing posts with the label Threads

Fork/Join Framework in Java — Parallelism with Work-Stealing

Image
The Fork/Join Framework (java.util.concurrent) is designed for parallelizing CPU-bound, divide-and-conquer tasks. It splits a big task into smaller subtasks (fork), runs them in parallel, and merges results (join). It's ideal for recursive algorithms (e.g., parallel sum, merge sort, matrix ops) and uses a work-stealing scheduler to balance load across worker threads. 1. When to use Fork/Join Large CPU-bound recursive tasks that can be divided into independent subtasks. Problems that follow divide-and-conquer pattern (array sum, parallel sort, tree algorithms). Not ideal for many short I/O-bound tasks — use ExecutorService for that. 2. Core Concepts ForkJoinPool — pool of worker threads optimized for Fork/Join tasks. ForkJoinTask — abstract base for tasks; two common subclasses: RecursiveTask<V> — returns a result. RecursiveAction — returns no result (void). Work-stealing — idle threads steal subtasks from busy threads...

ExecutorService, Future & CompletableFuture

Image
After understanding threads and multithreading basics, the next step in modern Java concurrency is learning how to manage threads efficiently. Manually creating threads is inefficient, difficult to control, and not scalable. Java solves these issues using ExecutorService, Future, and CompletableFuture. Why ExecutorService? ExecutorService provides a flexible framework for managing and reusing threads. It removes the need to manually create, start, and manage individual threads. Efficient resource utilization Thread reuse using thread pools Better performance Simpler asynchronous programming Avoids creating too many threads Types of Executor Services Java offers several ready-to-use executors based on usage: newSingleThreadExecutor: Executes tasks sequentially in one thread. newFixedThreadPool: Maintains a fixed number of threads. newCachedThreadPool: Creates threads as needed; good for short-lived tasks. newScheduledThreadPool: Executes delayed a...

Understanding Multiple Threads in Java

Image
Introduction In Java programming, achieving parallel execution of tasks is made possible using multithreading. This blog explores how to create and run multiple threads concurrently, why using start() is critical, how scheduling works, and additional tips like using sleep() for clearer outputs. Demonstrating Multiple Threads Let's start with a simple example. We define two threads—one to say “Hi” and another to say “Hello”. class HiThread extends Thread {   public void run() {     for(int i = 0; i < 5; i++) {       System.out.println("Hi");       try { Thread.sleep(500); } catch(Exception e) {}     }   } } class HelloThread extends Thread {   public void run() {     for(int i = 0; i < 5; i++) {       System.out.println("Hello");       try { Thread.sleep...

Threads in Java

Image
Introduction In modern applications, responsiveness and efficiency are essential. Whether you’re building a desktop app, a game, or a backend server, you often need to perform multiple tasks simultaneously. This is where Threads in Java come into play. Threads allow you to run multiple tasks concurrently, making programs faster and more efficient. In this blog, we’ll explore: What threads are and why they are important How to create and manage threads in Java The thread lifecycle Common problems like race conditions How to ensure thread safety What is a Thread? A thread is the smallest unit of execution in a program. While a process represents an entire running application, threads are lightweight sub-tasks inside that process. 👉 Example: When you use WhatsApp, one thread handles message sending, another handles receiving, while another manages notifications — all at the same time. This is possible because of multithreading , which enables multiple threa...