Skip to main content
Documents
Share
LinkedIn
Facebook
Twitter
Copy
Java keywordsIntroduction To JavaJava File HandlingJava Language BasicsJava ArraysJava Object-Oriented Programming

Java Threads

Java threads are a fundamental part of Java's concurrency model, allowing multiple tasks to run concurrently within a program. A thread is a lightweight process that enables parallel execution of code, improving application performance and responsiveness, especially in multi-core systems.

Usage

Threads are used in Java to perform background operations without interrupting the main program flow. They are ideal for tasks like handling user input, performing calculations, or managing I/O operations concurrently.

Creating Threads

Java provides two primary ways to create threads:

  1. Extending the Thread class
  2. Implementing the Runnable interface

Examples

Example 1: Extending the Thread Class


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

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

In this example, a new class MyThread extends the Thread class and overrides the run() method. The start() method is called to begin execution of the thread, which internally calls the run() method.

Example 2: Implementing the Runnable Interface


class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Thread is running.");
    }

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

Here, the MyRunnable class implements the Runnable interface and provides the run() method. A Thread object is created with an instance of MyRunnable and started using the start() method.

Example 3: Using Lambda Expressions


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

This example demonstrates creating a thread using Java 8's lambda expressions, which simplifies the syntax for implementing the Runnable interface.

Tips and Best Practices

  • Thread Safety: Ensure that shared resources are accessed in a thread-safe manner to prevent data inconsistency and race conditions. Use synchronization mechanisms like synchronized blocks or ReentrantLock.
    
    synchronized (lockObject) {
        // critical section
    }
                
  • Avoid Overuse: Creating too many threads can lead to resource exhaustion. Use thread pools (e.g., ExecutorService) to manage threads efficiently.
    
    ExecutorService executor = Executors.newFixedThreadPool(10);
    executor.execute(new MyRunnable());
    executor.shutdown();
                
  • Graceful Termination: Implement a mechanism to gracefully terminate threads when they are no longer needed. Use flags or interrupts to signal threads to stop.
    
    class MyRunnable implements Runnable {
        private volatile boolean running = true;
    
        public void run() {
            while (running) {
                // perform task
            }
        }
    
        public void stop() {
            running = false;
        }
    }
                
  • Use Higher-Level Concurrency Utilities: Consider using Java's concurrency utilities from the java.util.concurrent package, such as CountDownLatch, CyclicBarrier, and ConcurrentHashMap, to simplify complex concurrency tasks.
  • Handle Exceptions: Always handle exceptions within the run() method to prevent unexpected thread termination.
    
    public void run() {
        try {
            // perform task
        } catch (Exception e) {
            e.printStackTrace();
        }
    }