If you're interested in Java, then you'll probably have either come across or wondered what multithreading is. As one of the most sought-after topics in Java, we're giving you the inside scoop with this tech tutorial. We'll get you up and running with these and how you can write simple multithreaded programs. Multithreading is a very important concept and if used well, it can give you a lot of performance improvements in your application.
Before we get started, it's good to remember exactly how a single-threaded program runs before we get into a multithreaded example. Take a look below, this program will be used to print numbers starting from 1 to 100. We'll also write another function that will do the exact same thing but will be called from the main method.
In the example above, you can see two for loops that are used to print the numbers from 1 to 100. One loop is in the main method while the other one is inside a function. When we run this, we get the output of the for loop inside the function first followed by the output from the for loop inside the main method. This is a classic single-threaded application where the flow of execution follows a sequential order.
Okay great, so you remember what single threading does – let's get to multithreading!
There are two ways in which we can create multithreaded programs. The first way is to extend the Thread class. This is a class inside java.lang package and it has a method called run. We need to override this method and all of the programming logic of the particular thread will be present inside this method. Let’s take a look at the same example that we looked at earlier and make it multithreaded.
We made a few simple changes in the previous code. Let's go over these in detail:
- The first change is that we extended the Thread class to get all the threading capabilities.
- Then we overrode the run method which is the entry point for every thread.
- Inside that method, we put the logic to print numbers from 1 to 100.
- Inside the main method, we created an instance of our class. If we use the dot operator, we'd be able to see the start method present inside our class variable. This is because we extended the thread class.
Once you run the program, you'll see the following output.
You might not see the exact same output, but notice that the main thread started executing first even though the for loop is present after we called the start method. The numbers from 1 to 72 are printed on the console from the main thread after which we see that thread1 starts executing. This is an example of a simple multithreaded program. So, you might be wondering, why is this important? Why do I need two threads to print numbers?
So you don't actually need multithreaded programs for printing a set of numbers. But wait – hear us out. They'll make your life easier because they're used to exploit the processing resources that you have. It's mostly used for tasks that are independent of each other and those which don’t access the same data source at the same time.
Some useful methods in Multithreading
The sleep method on the thread class is a static method that has a single argument, which is the number of milliseconds. When using this method, that particular thread goes into sleep mode for the amount of time mentioned. During this period, the thread doesn’t perform anything. There are several uses use-cases for this method.
We’re pretty sure you might have seen applications that try connecting to third-party services but get a timeout error or that the service is unavailable. In such a scenario, the particular service on our end (which is connecting to the third party service) can have the sleep method to retry connecting to the server after a fixed amount of time. In the below example, you can see the sleep method being used within the for loop. It throws a checked exception which we have to handle using a try/catch block or a throws statement.
Next up, we have the join method. This is used to make sure that one thread waits until another thread completes execution. Take a look at the example below, and try to guess what the output of this program is:
Did you guess 3628800? Well, that is the answer for 10 factorial. But the above program will output 1. This is because even though we start thread1 before the print statement, it takes some time for execution while the main thread continues ahead with its execution. Therefore, we get the output as 1.
To get the right output, we need to make the main thread wait until thread1 finishes execution. This is where we use the join method. Like we did with the start method, we call the join method immediately after it. This will make the main thread wait until thread1 has finished execution and we'll get the right answer. Check it out:
This one throws an InterruptedException as well, so we need to handle it either using the throws statement or a try/catch block. The output of this program will be what we initially expected.
So that's it! We hope you had some fun coding multithreaded applications in Java. We will be seeing some more concepts like these in the upcoming articles with more byte-sized (badum tss!) code snippets that will make it so much easier for all of you to follow and implement.