> For the complete documentation index, see [llms.txt](https://www.pranaypourkar.co.in/the-programmers-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.pranaypourkar.co.in/the-programmers-guide/java/java-basics/parallelism-and-concurrency/thread-fundamentals/creating-threads.md).

# Creating Threads

## About

In Java, threads can be created and managed using multiple approaches. Each approach has its use cases and trade-offs. Some of the approaches are given below.

## **1. Extending the `Thread` Class**

* The simplest way to create a thread is by extending the `Thread` class.
* The `run()` method is overridden to define the thread's behavior.
* A new thread is started using the `start()` method.

**Example:**

```java
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " Thread is running...");
    }
}

public class SomeMain {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start(); // Start the thread
        
        // Thread-0 Thread is running...
    }
}
```

**Limitations:**

* Java **does not support multiple inheritance**, so extending `Thread` prevents extending other classes.
* Better to use the `Runnable` interface if we need more flexibility.

## **2. Implementing the `Runnable` Interface**

* Instead of extending `Thread`, the `Runnable` interface can be implemented.
* The `run()` method is implemented inside the class.
* The thread is started using `Thread` class.

**Example:**

```java
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " Thread is running...");
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
        // Thread-0 Thread is running...
    }
}
```

**Advantages:**

* Allows the class to **extend other classes** (unlike extending `Thread`).
* Encouraged in **multi-threaded environments** where tasks can be separated from threads.

## 3. Using `Callable` and `Future` (Return Value from Thread)

* The `Callable<T>` interface (from `java.util.concurrent`) allows a thread to return a result.
* The `Future<T>` interface is used to retrieve the result of the thread execution.

**Example:**

```java
import java.util.concurrent.Callable;

public class MyCallable implements Callable<String> {

    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    @Override
    public String call() throws Exception {
        return Thread.currentThread().getName() + " Thread executed!";
    }
}
```

```java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableExample {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = executor.submit(new MyCallable());

        System.out.println(future.get()); // Retrieves the result
        executor.shutdown();
        
        // pool-1-thread-1 Thread executed!
    }
}
```

**Advantages:**

* Unlike `Runnable`, `Callable` allows returning values and throwing exceptions.

## 4. Using Anonymous Class

* Instead of defining a separate class, threads can be created using an anonymous class.

**Example:**

```java
public class AnonymousExample {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " Thread is running...");
            }
        });
        thread.start();
        // Thread-0 Thread is running...
    }
}
```

**Use Case:**

* Useful for quick thread creation without creating separate classes.

## **5. Using Lambda Expressions (Java 8+)**

* Java 8 introduced lambda expressions, making it even more concise to create threads.

```java
public class AnonymousExample {
    // Using lambda expression
    public static void main(String[] args) {
        Thread thread = new Thread(() -> System.out.println(Thread.currentThread().getName() + " Thread is running..."));
        
        System.out.println(Thread.currentThread().getName() + " Current Thread is running...");
        thread.start();
        
        /* Output
        main Current Thread is running...
        Thread-0 Thread is running...
        */
    }
}
```

**Advantages:**

* **Reduces boilerplate code** for single-method interfaces like `Runnable`.

## 6. Using `ThreadPoolExecutor` (Efficient Thread Management)

* Instead of creating a new thread every time, **thread pools** reuse existing threads.
* `ThreadPoolExecutor` is a low-level API for managing thread pools.

**Example:**

```java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        for (int i = 1; i <= 5; i++) {
            executor.execute(() -> System.out.println(Thread.currentThread().getName() + " is running"));
        }
        executor.shutdown();
        
        /* Output
        pool-1-thread-1 is running
        pool-1-thread-2 is running
        pool-1-thread-3 is running
        pool-1-thread-2 is running
        pool-1-thread-1 is running
        */
    }
}
```

**Advantages:**

* **Reduces overhead** of creating/destroying threads frequently.
* **Better resource management** for high-load applications.

## **7. Using `ForkJoinPool` (Parallel Computing)**

* The **Fork-Join framework** is useful for parallel computing by dividing tasks into smaller subtasks.

**Example:**

```java
package practice;

import java.util.concurrent.RecursiveTask;

public class MyRecursiveTask extends RecursiveTask<Integer> {

    private int num;

    MyRecursiveTask(int num) {
        this.num = num;
    }

    protected Integer compute() {
        if (num <= 1) {
            return num;
        }
        MyRecursiveTask task1 = new MyRecursiveTask(num - 1);
        MyRecursiveTask task2 = new MyRecursiveTask(num - 2);
        task1.fork();
        return task2.compute() + task1.join();
    }
}
```

```java
import java.util.concurrent.ForkJoinPool;

public class ForkJoinExample {

    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        System.out.println(pool.invoke(new MyRecursiveTask(5))); // 5
    }
}
```

**Use Case:**

* Suitable for **divide-and-conquer algorithms** like **parallel recursion** and **large dataset processing**.

## **8. Using `Virtual Threads` (Java 19+)**

* **Virtual Threads** (introduced in Java 19) allow lightweight, high-performance thread execution.
* Unlike OS threads, millions of virtual threads can be created without performance issues.

**Example:**

```java
public class VirtualThreadExample {
    public static void main(String[] args) {
        Thread.startVirtualThread(() -> System.out.println("Virtual thread running..."));
    }
}
```

**Advantages:**

* Extremely lightweight, **highly scalable**, and does not consume OS resources like traditional threads.
* Ideal for handling **highly concurrent workloads** efficiently.

## **Comparison of Thread Creation Methods**

<table data-full-width="true"><thead><tr><th width="287">Approach</th><th width="105">Flexibility</th><th width="131">Can Return Value?</th><th width="306">Suitable For</th><th>Complexity</th></tr></thead><tbody><tr><td>Extending <code>Thread</code></td><td>Low</td><td>No</td><td>Simple tasks</td><td>Low</td></tr><tr><td>Implementing <code>Runnable</code></td><td>Medium</td><td>No</td><td>Basic concurrency</td><td>Low</td></tr><tr><td>Using <code>Callable</code> &#x26; <code>Future</code></td><td>Medium</td><td>Yes</td><td>Background tasks needing results</td><td>Medium</td></tr><tr><td>Using Anonymous Class</td><td>Medium</td><td>No</td><td>Quick thread execution</td><td>Low</td></tr><tr><td>Using Lambda Expressions</td><td>Medium</td><td>No</td><td>Shorter syntax</td><td>Low</td></tr><tr><td>Using <code>ThreadPoolExecutor</code></td><td>High</td><td>No</td><td>Managing large tasks efficiently</td><td>Medium</td></tr><tr><td>Using <code>ForkJoinPool</code></td><td>High</td><td>Yes</td><td>Parallel processing, recursion</td><td>High</td></tr><tr><td>Using <code>Virtual Threads</code></td><td>High</td><td>No</td><td>Highly scalable concurrency</td><td>Low</td></tr></tbody></table>

## **Main Thread and New Thread Running Parallelly**

After creating a new thread, the **main thread** continues to execute **concurrently** (parallelly) with the newly created thread.

### Example

```java
public class MyThread extends Thread {

    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("Child Thread: " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
```

```java
public class MainThreadExample {

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start(); // New thread starts

        // Main thread continues to execute in parallel
        for (int i = 1; i <= 5; i++) {
            System.out.println("Main Thread: " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        
        /* Output - The output order may vary due to thread scheduling
        Child Thread: 1
        Main Thread: 1
        Main Thread: 2
        Child Thread: 2
        Main Thread: 3
        Child Thread: 3
        Main Thread: 4
        Child Thread: 4
        Main Thread: 5
        Child Thread: 5 
        */
    }
}
```

### **How it Works?**

1. The **main thread** starts execution from `main()`.
2. It creates a **new thread** (`MyThread`) and starts it using `start()`.
3. The **new thread** (`run()`) runs **independently** while the **main thread** continues executing its own tasks.
4. **Both threads execute concurrently**, and the **CPU switches** between them using the **scheduler**.

### **Concurrency vs. Parallelism**

1. **Concurrency**:
   * Multiple threads/tasks **overlap** in execution but may **not execute at the exact same instant**.
   * The **CPU switches** between threads rapidly, giving the illusion of simultaneous execution.
   * Occurs in **single-core** or **multi-core** systems.
2. **Parallelism**:
   * Multiple threads/tasks **execute at the exact same time** on **different CPU cores**.
   * Requires a **multi-core processor** to truly run tasks simultaneously.

### **Why "Both threads execute concurrently" and not "parallelly"?**

* In Java, when we create a new thread, it **does not guarantee** that it will run **on a separate core**.
* Java threads are managed by the **JVM and the OS scheduler**, which may **time-share** them on a single CPU.
* If we have a **single-core CPU**, the threads can only run **concurrently** by switching back and forth.
* If we have a **multi-core CPU**, the threads **may** run truly in parallel, but this depends on OS scheduling.

### **Example of Concurrency vs. Parallelism**

**1. Concurrent Execution (Single-Core CPU)**

```
Time  | Thread-1 | Thread-2
--------------------------------
T1    | Running  | -
T2    | -        | Running
T3    | Running  | -
T4    | -        | Running
```

*(Threads switch rapidly, but only one runs at a time.)*

**2. Parallel Execution (Multi-Core CPU)**

```
Time  | Thread-1 | Thread-2
--------------------------------
T1    | Running  | Running
T2    | Running  | Running
T3    | Running  | Running
```

*(Both threads run simultaneously on different CPU cores.)*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://www.pranaypourkar.co.in/the-programmers-guide/java/java-basics/parallelism-and-concurrency/thread-fundamentals/creating-threads.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
