Multithreading is a fundamental feature of Java that allows concurrent execution of two or more parts of a program. In Java, there are two main ways to create threads: using the Thread class and the Runnable interface. Both methods are commonly used to achieve multithreading, but they differ in their implementation and use cases. This article explains the step-by-step process of creating threads using these two approaches, along with examples.
The Thread class is part of the java.lang
package and represents a thread of execution in a program.
You can create a thread by either subclassing the Thread
class or by passing a Runnable
object to it.
To create a thread using the Thread
class, you need to:
Thread
class.run()
method to define the code that the thread will execute.Thread
class and invoke the start()
method to begin execution.// Subclass the Thread class class MyThread extends Thread { @Override public void run() { System.out.println("Thread is running using Thread class"); } } public class ThreadClassExample { public static void main(String[] args) { // Create an instance of the Thread subclass MyThread thread = new MyThread(); // Start the thread thread.start(); } }
In this example, the MyThread
class extends the Thread
class and overrides the run()
method
to print a message. The start()
method is used to begin the execution of the thread.
The Runnable interface is a functional interface with a single method: run()
. It is often preferred over
subclassing the Thread
class because it allows your class to extend another class while still providing thread functionality.
To create a thread using the Runnable
interface, you need to:
Runnable
interface in your class.run()
method to define the task for the thread.Runnable
instance to a Thread
object and call its start()
method.// Implement the Runnable interface class MyRunnable implements Runnable { @Override public void run() { System.out.println("Thread is running using Runnable interface"); } } public class RunnableInterfaceExample { public static void main(String[] args) { // Create an instance of MyRunnable MyRunnable myRunnable = new MyRunnable(); // Pass the Runnable instance to the Thread constructor Thread thread = new Thread(myRunnable); // Start the thread thread.start(); } }
In this example, the MyRunnable
class implements the Runnable
interface, and the run()
method
is overridden to define the task. We then create a Thread
object and pass the Runnable
instance to it before
starting the thread using the start()
method.
Both Thread
class and Runnable
interface are useful for creating threads, but there are important
differences:
Thread
class, your class becomes a thread, and you can directly override
the run()
method. However, it restricts your ability to extend other classes since Java allows only single inheritance.Runnable
interface allows your class to extend another class, providing
more flexibility. The run()
method in the Runnable
interface is executed when you pass the instance
to a Thread
object.
You can combine both approaches to create more flexible thread execution. For example, you can implement the Runnable
interface and then pass it to a Thread
object to start execution.
// Runnable implementation class MyRunnable implements Runnable { @Override public void run() { System.out.println("Thread is running using Runnable interface"); } } // Thread subclass class MyThread extends Thread { @Override public void run() { System.out.println("Thread is running using Thread class"); } } public class ThreadAndRunnableExample { public static void main(String[] args) { // Create a thread using Runnable Runnable runnable = new MyRunnable(); Thread thread1 = new Thread(runnable); thread1.start(); // Create a thread using Thread class MyThread thread2 = new MyThread(); thread2.start(); } }
In this example, both the Runnable
interface and the Thread
class are used to create and start threads.
When dealing with multiple threads, you can create several instances of Thread
or Runnable
and execute them
simultaneously. This is how multithreading is used to perform tasks concurrently.
// Runnable implementation class MyRunnable implements Runnable { private String message; public MyRunnable(String message) { this.message = message; } @Override public void run() { System.out.println(message); } } public class MultipleThreadsExample { public static void main(String[] args) { // Create multiple threads Thread thread1 = new Thread(new MyRunnable("Thread 1 is running")); Thread thread2 = new Thread(new MyRunnable("Thread 2 is running")); Thread thread3 = new Thread(new MyRunnable("Thread 3 is running")); // Start the threads thread1.start(); thread2.start(); thread3.start(); } }
In this example, we create and start multiple threads that print different messages. Each thread runs concurrently, allowing for parallel execution of tasks.
Creating threads in Java can be done using either the Thread
class or the Runnable
interface, each offering
different advantages. The Thread
class is simpler for basic use cases, while the Runnable
interface is
preferred when more flexibility is needed, such as when you want your class to extend another class. Both approaches allow for
efficient multithreading in Java, and the choice of method depends on the specific requirements of your program.