Java
Multithreading
Concurrency
Thread Management
Method Invocation

How to call a method with a separate thread in Java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Calling a method with a separate thread in Java is a fundamental concept linked to parallel processing. Leveraging threads allows programs to perform multiple tasks concurrently, which can enhance the performance of applications significantly, especially those with computationally intensive operations or those that wait for some resources like file I/O or network operations. This article explores the fundamental concepts, demonstrates how to implement threading in Java, and provides examples to solidify understanding.

Understanding Threads in Java

Java provides built-in support for multithreaded programming through its java.lang.Thread class and the java.util.concurrent package. A thread in Java is essentially a lightweight subprocess; the smallest unit of processing. In Java, threading can be achieved primarily by two methods:

  1. Extending the Thread Class: Subclassing the Thread class and overriding its run method.
  2. Implementing the Runnable Interface: Implementing the Runnable interface because Java does not support multiple inheritance, making this approach more flexible and widely used.

Creating a Thread by Extending the Thread Class

When you extend the Thread class, you create a thread by defining a new class and overriding the run method. Here's a technical explanation along with an example:

java
1class MyThread extends Thread {
2    @Override
3    public void run() {
4        System.out.println("Executing in a separate thread: " + Thread.currentThread().getName());
5    }
6}
7
8public class ThreadExample {
9    public static void main(String[] args) {
10        MyThread thread = new MyThread();
11        thread.start(); // Start the thread
12    }
13}

Key Points:

  • Subclass the Thread Class: Create a class that extends Thread.
  • Override the run() Method: Override the run method to insert the code that should be executed by the thread.
  • Invoke start(): Call the start method on the thread object to initiate a new thread of execution.

Creating a Thread by Implementing the Runnable Interface

To achieve more flexibility, implement the Runnable interface. This method is preferred as it allows other inheritance in your class.

java
1class MyRunnable implements Runnable {
2    @Override
3    public void run() {
4        System.out.println("Executing in a separate thread: " + Thread.currentThread().getName());
5    }
6}
7
8public class RunnableExample {
9    public static void main(String[] args) {
10        Thread thread = new Thread(new MyRunnable());
11        thread.start();
12    }
13}

Key Points:

  • Implement the Runnable Interface: Create a class that implements Runnable.
  • Override the run() Method: Implement the run method with the code for the task.
  • Pass Runnable to Thread: Create an instance of Thread, passing it the Runnable implementation, and call start to execute the thread.

Advantages of Using Runnable Over Thread

  • Decoupled Design: Allows implementing the Runnable interface and extending another base class.
  • Reusability: The Runnable can be executed by several threads, making object design cleaner.

Using the Executor Framework

For better scalability and management of threads, Java introduced the Executor framework which provides thread pool functionality.

java
1import java.util.concurrent.ExecutorService;
2import java.util.concurrent.Executors;
3
4public class ExecutorExample {
5    public static void main(String[] args) {
6        ExecutorService executorService = Executors.newFixedThreadPool(2);
7
8        executorService.submit(new MyRunnable());
9        executorService.submit(new MyRunnable());
10
11        executorService.shutdown();
12    }
13}

Key Points:

  • Fixed Thread Pool: Allows running predetermined maximum threads concurrently. Consider using Executors.newFixedThreadPool().
  • Submit Tasks: submit method places tasks into the thread pool for execution.
  • Graceful Shutdown: shutdown() ensures orderly termination, executing previously submitted tasks.

Table Summarizing Key Points

AspectThread ClassRunnable InterfaceExecutor Framework
Extends or ImplementsExtends ThreadImplements RunnableUsed with Callable & Runnable
Inheritance UsageNot possible to extend another classAllows to extend other classesNot applicable
Ease of Thread ManagementManual thread managementManual thread managementManaged by Executors
Reuse of Runnable ObjectsNot reusableReusableHighly reusable in a thread pool
Thread HandlingCalls start() on ThreadPass to Thread and then call start()Uses submit() to execute threads

Conclusion

Calling a method in a separate thread in Java enables a high degree of parallelism in applications. By understanding the different approaches—extending Thread, implementing Runnable, or leveraging the Executor framework—you can choose the best method to suit your application requirements, balancing simplicity with powerful features for efficient thread management. This flexibility in Java enhances both performance and responsiveness in applications, essential in modern software development.

With this knowledge, one can more effectively design multithreaded applications to leverage multi-core processors and provide a smoother, more responsive user experience.


Course illustration
Course illustration

All Rights Reserved.