Java Threads
gocourse.in Maintenance

We'll be back soon

Our CDN (cdn.gocourse.in) is currently unreachable. Some images, JavaScript, or CSS files may not load properly.

Estimated downtime: ~30 minutes

Java Threads

Harine

Java Threads

What are Java Threads?

A thread in Java is a lightweight unit of execution that allows a program to perform multiple tasks simultaneously. This concept is known as multithreading, and it plays a crucial role in building high-performance and responsive applications.

Threads are commonly used for:

  • Background processing (e.g., file downloads, data fetching)
  • Performing multiple operations concurrently
  • Improving application responsiveness

Why Use Multithreading in Java?

Using threads provides several advantages:

  • Better Performance: Execute multiple tasks in parallel
  • Improved Responsiveness: Prevent UI or main program blocking
  • Efficient Resource Utilization: Maximize CPU usage

Ways to Create Threads in Java

Java provides two primary approaches to create threads:

1. Extending the Thread Class

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

Example: Creating a Thread Using Thread Class

class DataProcessor extends Thread {

   @Override

   public void run() {

     System.out.println("Processing data in a separate thread...");

   }

   public static void main(String[] args) {

      DataProcessor thread = new DataProcessor();

      thread.start();

      System.out.println("Main thread execution continues...");

    }

  }

2. Implementing the Runnable Interface

A more flexible approach is to implement the Runnable interface and pass it to a Thread object.

Example: Creating a Thread Using Runnable

class TaskHandler implements Runnable {

    @Override

    public void run() {

       System.out.println("Executing task using Runnable...");

    }

    public static void main(String[] args) {

       TaskHandler task = new TaskHandler();

       Thread thread = new Thread(task);

       thread.start();

       System.out.println("Main thread is still running...");

      }

   }

Thread Lifecycle Basics

A thread goes through several stages:

  • New → Thread object created
  • Runnable → Ready to run
  • Running → Currently executing
  • Terminated → Execution completed

Understanding Concurrency Issues

When multiple threads access shared resources, the program may produce unexpected results.

This is known as a concurrency problem or race condition.

Example: Race Condition

class CounterThread extends Thread {

   static int counter = 0;

   @Override

   public void run() {

     counter++;

   }

   public static void main(String[] args) {

      CounterThread t1 = new CounterThread();

      CounterThread t2 = new CounterThread();

      t1.start();

      t2.start();

      System.out.println("Counter value: " + counter);

     }

   }

Issue

The output may vary because both threads modify counter at the same time without synchronization.

Avoiding Concurrency Problems

To handle concurrency safely, Java provides multiple techniques such as synchronization, locks, and thread coordination.

Example: Using join() to Ensure Execution Order

class SafeCounter extends Thread {

   static int count = 0;

   @Override

   public void run() {

      count++;

    }

    public static void main(String[] args) throws InterruptedException {

       SafeCounter thread = new SafeCounter();

       thread.start();

       // Wait for the thread to finish

       thread.join();

       System.out.println("Final count: " + count);

     }

  }

Why Use join()?

  • Ensures the thread completes before the main thread continues
  • Prevents inconsistent or unpredictable results

Additional Thread Utility Methods

  • start() → Starts a new thread
  • run() → Contains thread logic
  • join() → Waits for thread completion
  • isAlive() → Checks if a thread is still running
  • sleep(ms) → Pauses execution for a specified time

Our website uses cookies to enhance your experience. Learn More
Accept !