Before we get into thread implementation in Java, let us spend some time and understand the idea and concepts behind threads and concurrent programming.
What is Concurrency
Applications are expected to do more than one task at the same time in parallel. Applications which do more than one tasks at a time are called concurrent applications. An example of such concurrent software application is streaming audio application. It must read the digital audio from the network, decompress, manage playback and update the audio simultaneously.
Process and Thread
There are two basic units in the concurrent programming namely Process and Thread. In Java, the concurrent programming is implemented using Threads. Each operating system consists of many processes running to achieve different tasks. Each process has its own memory space. As a matter of fact, JVM (Java Virtual Machine) runs as a single process. A Process contains one more Threads. Each and every Thread which belongs to a Process can share Process’s resources, memory and files.
Implementing Threads
Now, we have a good understanding of what is a process and thread. In Java, each thread is an instance of a class Thread. There are two ways to create a thread. The following two sections discuss about these two ways to create and start threads:
By Implementing Runnable Interface
The ‘Runnable’ interface contains a single method called ‘run()’ which contains the code to be executed in the thread. Once the thread instance is created and ‘start()’ method is called on the thread, JVM creates a thread and invokes ‘run()’ method.
public class MyRunnable implements Runnable {
public void run() {
System.out.println(“My first thread is running…”);
}
public static void main(String… args) {
new Thread(new MyRunnable()).start();
}
}
The above snippet of code creates a thread class by implementing ‘Runnable’ interface and by providing implementation for method ‘run()’. The ‘run()’ method will contain the execution logic for the thread to execute. After that, in the main() method we created an instance of the class which implements Runnable interface, and passed that instance to the new Thread object. Finally, we called ‘start()’ to start the thread execution.
Why calling start() method invokes run() method
In order to spawn a new thread, we need to call ‘start()’ method. Calling ‘run()’ method directly will execute current thread’s ‘run()’ method. So for this reason we need to call ‘start()’ method. Once the ‘start()’ method is called, JVM creates a new thread instance and executes newly created thread’s ‘run()’ method. Before calling ‘start()’ method on a Thread instance, the thread will be in new state. This means that, we only have a Thread object not running thread. Once we call ‘start()’ method on the thread instance, the following actions happen:
- New thread of execution starts
- Thread moves from new state to runnable state
- Thread’s ‘run()’ method will be executed
In fact, every Java program runs in a thread, we can call it the ‘main’ thread. In the above code example, we instantiated and started a thread from our main thread.
By Extending Thread Class
We can also create threads by extending Thread class and by overriding ‘run()’ method. This is because the Thread class itself implements Runnable interface. The following code sample shows how to create and start a thread by extending Thread class.
public class MyThread extends Thread {
public void run() {
System.out.println(“My new thread from Thread class”);
}
public static void main(String… args) {
new MyThread().start();
}
}
As we see the previous code example, we straightaway created our thread instance and started the thread by calling its ‘start()’ method.
Implementing Runnable vs. Extending Thread Class
As we already discussed we have two ways to create and start threads in Java. The following two points summarizes these two strategies and discusses which approach is most benefited.
- Thread creation by implementing Runnable interface abstracts thread management from the rest of our application. Once we have a thread instance we simply pass it to the executor which actually executes the thread.
- Thread creation by extending Thread class is probably simple to code. This way we can directly control and manage the thread creation. However, this approach has a drawback that, once a class extends Thread class, it cannot extend any other class. As we already know, Java allows only one class to extend as parent class.
So the recommended way to create threads is by implementing Runnable interface. But, extending Thread class also fine provided that application requirements demands that. In terms of functionality and thread execution, there will not be any difference with respect to the above two approaches.
- Top 45 Fresher Java Interview Questions - March 9, 2023
- 25 Free Practice Questions – GCP Certified Professional Cloud Architect - December 3, 2021
- 30 Free Questions – Google Cloud Certified Digital Leader Certification Exam - November 24, 2021
- 4 Types of Google Cloud Support Options for You - November 23, 2021
- APACHE STORM (2.2.0) – A Complete Guide - November 22, 2021
- Data Mining Vs Big Data – Find out the Best Differences - November 18, 2021
- Understanding MapReduce in Hadoop – Know how to get started - November 15, 2021
- What is Data Visualization? - October 22, 2021