C

Core Java tutorial for beginners

Clean • Professional

What is Thread in Java – Process vs Thread & Thread Creation Explained

4 minute

Thread in Java

A Thread is the smallest unit of execution inside a program. It allows Java applications to run multiple tasks at the same time, improving performance, responsiveness, and CPU utilization.


What Is a Thread?

A Thread is a lightweight, independent unit of execution:

  • Has its own execution path
  • Runs independently
  • Shares memory with other threads
  • Managed by JVM Thread Scheduler

Java programs start with one main thread, but you can create multiple threads to run tasks concurrently.

Example:

  • Thread 1 → Load images
  • Thread 2 → Fetch notifications
  • Thread 3 → Play music

All tasks run simultaneously.


JVM Thread Scheduler

  • Schedules threads based on thread priority + OS scheduling algorithm
  • Execution order is unpredictable
  • Higher priority threads may not always run first
  • Output may vary on each program run

Process vs Thread

Understanding the difference is essential:

Process

  • A program in execution
  • Has its own memory space
  • Heavy & expensive to create
  • Does not share data with other processes

Example: Chrome browser, VS Code, IntelliJ

Thread

  • A smaller part of a process
  • Shares memory with other threads
  • Lightweight and fast to create
  • Communicates easily with other threads

Example inside Chrome:

  • Thread 1 → handles UI
  • Thread 2 → loads web pages
  • Thread 3 → downloads files

Process vs Thread Comparison Table:

FeatureProcessThread
DefinitionIndependent program in executionLightweight unit of execution inside a process
Memory SpaceOwn separate memoryShares process memory
CommunicationSlow, requires IPCFast, via shared memory
Creation CostHeavyLightweight
IsolationFully isolatedNot isolated, shares resources
Crash ImpactOne process crash does not affect othersOne thread crash can affect entire process
ExecutionRuns independentlyRuns inside a process
Context SwitchingSlowFast
Resource UsageHighLow
Use CaseRunning applicationsMultitasking inside an app

Creating Threads in Java

In Java, threads are created to perform multiple tasks concurrently. There are two main ways to create threads:

learn code with durgesh images

1. Extending the Thread Class

You can create a new thread by extending the Thread class and overriding its run() method.

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

public class Main {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start(); // Start a new thread
    }
}

Notes:

  • Use start() to begin the thread, which internally calls run().
  • Avoid calling run() directly – it executes in the main thread, not a new thread.
  • Limitation: Java doesn’t support multiple inheritance, so extending Thread may not be ideal for large projects.

2. Implementing the Runnable Interface (Recommended)

A more flexible way is to implement the Runnable interface, especially when you want your class to extend another class.

class MyTask implements Runnable {
    @Override
    public void run() {
        System.out.println("Task is running...");
    }
}

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyTask());
        thread.start();
    }
}

Advantages:

  • Supports extending other classes.
  • Allows reusing the same task in multiple threads.
  • Works seamlessly with the Executor framework.

3. Using Lambda Expressions (Modern & Clean)

With Java 8+, you can create threads using lambda expressions since Runnable is a functional interface.

public class Main {
    public static void main(String[] args) {
        Thread t = new Thread(() -> System.out.println("Thread running using lambda!"));
        t.start();
    }
}

Advantages:

  • Concise and modern syntax.
  • Perfect for small, simple tasks.

4. Using the Executor Framework (Thread Pool)

Instead of manually creating threads, you can use ExecutorService to manage thread pools efficiently.

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

public class Main {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);

        Runnable task1 = () -> System.out.println("Task 1 running");
        Runnable task2 = () -> System.out.println("Task 2 running");
        Runnable task3 = () -> System.out.println("Task 3 running");

        executor.submit(task1);
        executor.submit(task2);
        executor.submit(task3);

        executor.shutdown(); // Stop accepting new tasks
    }
}

Advantages:

  • Manages thread lifecycle automatically.
  • Reuses threads, improving performance.
  • Ideal for high-concurrency applications.

Complete Thread Example

Thread t1 = new Thread(() -> {
    for(int i = 1; i <= 5; i++)
        System.out.println("Thread 1: " + i);
});
Thread t2 = new Thread(() -> {
    for(int i = 1; i <= 5; i++)
        System.out.println("Thread 2: " + i);
});
t1.start();
t2.start();

Output (interleaved):

Thread 1: 1
Thread 2: 1
Thread 1: 2
Thread 2: 2
...

Points to Remember

  • A Thread is the smallest unit of execution in Java.
  • Java starts with the main thread, and you can create more threads as needed.
  • Threads share the same memory, so synchronization is required to avoid issues.
  • Thread execution is unpredictable due to the JVM and OS schedulers.
  • Always use start() to run a new thread.
  • Prefer Runnable or ExecutorService (thread pools) instead of extending Thread.
  • Improper synchronization may cause race conditions and deadlocks.
  • Use concurrency tools like synchronized, locks, and volatile for thread safety.
  • Multithreading improves performance and responsiveness, but too many threads can reduce performance.

Article 0 of 0