Multithreading is a way for us to execute the same process across multiple threads. A thread can be understood as a small unit which executes a program/process. A process can be executed by multiple threads at the same time simultaneously, this is known as multithreading. These threads can share the same resources like memory, but they can also have their own independant resources. Threads have their own program counters, stack and even their own registers. This allows for independant processing across threads, which means that the output of a single thread is independant of other threads. This means that even if a particular thread runs into a problem or exception the processing of other threads will not be affected by it. This is a major advantage when it comes to multithreading. Let us understand this with a further example :
let us assume there is a single taxi standing outside a busy airport. Assuming that the passengers arriving use only taxis to commute to their hotels, the taxi driver will have to make successive trips to drop all the passengers to their respective hotels. This will be a very time consuming process and labour intensive on the taxi driver as he will have to drop all the passengers one after the other. This problem can be fixed by having multiple taxis available. This approach divides the load and makes the process much faster also without tiring out the drivers too much.
Multithreading therefore allows us to run several threads in parallel, taking advantage of multi-core processors to perform tasks concurrently.
Let us try to understand how multithreading can be implemented in java. There are two ways in which this can be achieved :
-
- Extending Thread in the class where multithreading is performed.
- Implementing the Runnable method.
Extending Thread
First we create a class and extend Thread as te name suggests, inside it we will override the run() method. Inside the run() method you should put the code for the process that you want a single thread to or each thread to perform. This can be as simple as counting from 1 to 5 or as complex as simultaneously running different data points through a machine learning model. Make sure to use a try-catch block inside the run method to handle the exceptions. Once we have defined the task for each thread we will create an object of the class in our main method and use the start() method to begin the execution of a new thread. When the start() method is called the JVM(java virtual machine) creates a new thread and invokes its run() method.
So if you want 10 threads to perform the mentioned task then you should create 10 different objects and call the start() method for each of them. This can be done simply using a for loop.
package Multithreading; import java.util.Date; class MultithreadingClass extends Thread { @Override public void run() { try{ for(int i = 0; i < 5; i++){ Date d = new Date(); System.out.println("Thread " + Thread.currentThread().threadId() + " is running at : " + d); Thread.sleep(1000); } } catch (Exception e){ System.out.println("Exception is caught : " + e); } } } public class DateTime { public static void main(String[] args) { int n = 5; for (int i = 0; i < n; i++) { MultithreadingClass object = new MultithreadingClass(); object.start(); } } }
We can visualise the working of this in real-time even better if we use the command ‘Thread.sleep(1000)’ immediately after it performs the task in the run() method. This stops the processing of each thread for exactly 1000 milliseconds or 1 second after completing their single task.
Implementing Runnable
Since we are not extending Thread anymore we cannot call the start() method directly in our main method. Instead we will create a new Thread in the main method and pass in the object of the class that implements the Runnable Interface. Now we can call the start() method for the Thread.
package Multithreading; import java.util.Date; class MultithreadingClass implements Runnable { @Override public void run() { try{ for(int i = 0; i < 5; i++){ Date d = new Date(); System.out.println("Thread " + Thread.currentThread().threadId() + " is running at : " + d); Thread.sleep(1000); } } catch (Exception e){ System.out.println("Exception is caught : " + e); } } } public class DateTime { public static void main(String[] args) { int n = 5; for (int i = 0; i < n; i++) { MultithreadingClass object = new MultithreadingClass(); Thread T = new Thread(object); T.start(); } } }
The output for the above code looks like this
From this we can clearly see that 5 threads are working simultaneously, i.e. Threads – 29, 30, 31, 32, and 33. Note that in each cycle the threads are not printing in the same order, which means some threads finish the same task faster than others and it cannot be predicted which thread will be faster as it is random and it depends on the systems resource allocation.
Be First to Comment