The website content discusses Java multithreading using Thread and Runnable interfaces to improve application response times by handling customer and transaction data retrieval in parallel.
Abstract
Java multithreading is a powerful feature that allows developers to create efficient and responsive applications by leveraging concurrent execution. The website content provides a tutorial on using Java's Thread and Runnable interfaces to perform independent tasks, such as fetching customer data and purchase transactions, simultaneously. By doing so, the application's response time is significantly reduced from 15 seconds to 10 seconds. The tutorial illustrates this concept through a Java application that interacts with dummy clients to simulate network communication latency. It demonstrates the creation of separate classes that either extend the Thread class or implement the Runnable interface to handle different tasks concurrently. The content also acknowledges the evolution of Java's multithreading APIs and suggests that while the basic approach discussed is educational, it is not recommended for production due to the availability of more advanced tools in Java.
Opinions
The author believes that understanding the basic multithreading approach is important for appreciating the evolution of Java's concurrency tools.
It is noted that the traditional method of multithreading in Java by extending Thread or implementing Runnable is verbose and has limitations, such as difficulty in exception handling and the inability of the run method to return values directly.
The author suggests that Java's multithreading capabilities have improved significantly, implying that modern alternatives to the basic approach are preferable for practical use.
The tutorial encourages readers to engage by liking, following, and reaching out with questions or suggestions, indicating the author's commitment to community interaction and continuous learning.
Java Multithreading using Thread and Runnable
Multithreading not just allows programmers to create responsive and fast applications but will enable them to use hardware efficiently. Java has supported multithreading since the beginning and continues to evolve. This tutorial is about the primary use of multithreading in Java.
The setup:
The tutorial is based on the Java application that handles information about customers and their purchase transactions. We provide an id of the customer and the application sends the request to the service that handles purchase transactions then sends a request to the service that returns data about the customer, combines this information, and returns it.
This is a basic scenario, it will make it easy to understand multithreading. To obtain the information described above the app will use dummy clients that are mimicking the real services. To simulate the network communication latency the sleep method is added for each client. It takes 5 seconds to get the data of the customer and to get the purchase transactions of the customer it takes 10 seconds.
The challenge:
Our application takes on average 15 seconds to respond. Because first, we have to wait for a response from the customer purchase transaction client, and then we have to wait for more for the response from the customer data client.
So we got a new requirement to reduce the response time. As you already can see, the calls for customer data client and customer purchase transaction client are independent hence can be made at the same. The decision is to leverage Java Multithreading by splitting client calls into two different threads.
To get purchase transactions we will create a class that extends the Thread class. This class will have a constructor which accepts an id of a customer as a parameter. Then we have to override the run method of a Thread class. In this method, we will call the customer purchase transaction client and save the return into the list. This list is a class variable and to make it accessible from the outside of the class we will add the public get method.
To summarise we basically created the “wrapper class” that has one special method and from this method, we perform an action that has to be executed in a separate thread.
The same approach we will use to obtain the customer data. But in this case, the “wrapper class” will implement the Runnable interface instead of extending the Thread class.
In the main method of the application, we have two methods. The first uses a single thread and doesn't need any introduction
The second method uses the multithreading approach. First, we create the instances of the class that extends the thread, then we create an instance of the class that implements the Runnable. In the case of a Runnable implementation, we have to create the object from the Thread class and pass the instance of the runnable to its constructor. So basically when using Runnable implementation we have to add one more step in comparison with extending a Thread class.
After thread creation, we have to start them by calling a start method. The join method has to be called on each thread. The join method allows each tread to complete its part, before continuing in a single thread.
To see better the thread execution in the console the name of the thread can be set.
Now as the calls to the clients are performed in different threads, the call to get the customer data can start at the same time as the call to get the purchase transaction. So now the response time decreased from 15 to 10.
You can get the source code of the project from Git Hub and check it on your own. The code has timestamps at the beginning and the end of execution to check the duration it takes to run the code.
As you can see this approach of using multithreading is verbose because we had to create separate classes to run the tasks in different threads. Another point is that the run method is of type void, so it doesn't return anything. That is why we had to create the class variable and the get method so the result of execution of the run method could be accessible from the outside of the class. Another disadvantage is exception handling. It is very difficult and very inconvenient.
The good thing is that as I said before the Java language is evolving constantly and it has improved significantly the APIs for multithreading.
Conclusion
This tutorial is about multithreading in Java language using a basic approach. It is not recommended to use it in production because now Java has better tools for this. But it is always good to know how it was made before to understand further evolution of the tools that are available today. Stay tuned for new tutorials on this topic. Thank you for reading! Please like and follow. Please feel free to write in the comment section or on my LinkedIn account if you have any questions or suggestions.