
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Different Approaches to Concurrent Programming in Java
In Java, concurrent programming is a technique that allows multiple tasks or processes to run simultaneously on a single processor or multiple processors. It can improve the performance and responsiveness of applications. However, it also introduces new challenges and complexities to the Java developers, such as synchronization and deadlock. In this article, we will explore some of the different approaches to concurrent programming such as multithreading and executors.
Concurrent Programming in Java
The following three components of Java are used for Concurrent Programming
java.lang.Thread clas
java.lang.Runnable
java.util.concurrent
Multithreading
It is a feature of the Java programming language that allows us to perform multiple operations simultaneously. In it, the operation gets divided into multiple smaller parts called a thread. Each thread performs one independent task without affecting the other thread's performance. The main benefit of multithreading is the optimal use of resources like CPU and it boosts the execution time of allocated operations.
There are two ways to create threads in Java
By implementing Runnable Interface
By extending Thread class
In our next example, we will create threads by extending Thread class
Syntax
class nameOfThread extends Thread { // operations }
Approach
Create a class named ?Thrd' and inside it define a static method named ?operation()' along with an argument.
Now, in this method, take a for loop that will run 4 times and increment the given argument. The try block of this loop will print the output with a specified time interval i.e. 1000 milliseconds
Moving further, create three Threads. Inside these threads pass the arguments to the ?operation()' method.
At last, in the main method create three objects for the thread class and execute them using the inbuilt method ?start()'.
Example of Thread
The following example demonstrates what we have discussed till this point about multithreading
class Thrd { public static void operation(int data) { for(int i = 1; i <= 4; i++) { System.out.println(data++); try { // each iteration performed with interval of 1 sec Thread.sleep(1000); } catch(Exception exp){} } } } class Thrd1 extends Thread { // thread number 1 public void run() { Thrd.operation(1); } } class Thrd2 extends Thread { // thread number 2 public void run() { Thrd.operation(5); } } class Thrd3 extends Thread { // thread number 3 public void run() { Thrd.operation(10); } } public class ThrdExecution { public static void main(String args[]) { // creating object for thread class Thrd1 oprt1 = new Thrd1(); Thrd2 oprt2 = new Thrd2(); Thrd3 oprt3 = new Thrd3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } }
Output
1 10 5 2 11 6 3 12 7 4 13 8
Executor
It is an interface of Java Concurrent API that can initiate and control the thread execution. It defines three predefined classes named ThreadPoolExecutor, ForkJoinPool, and ScheduledThreadPoolExecutor. These classes further implements Executor and ExecutorService interfaces to manage threads.
But, most of the time we use static factory methods for creating different kinds of executor services defined by the Executors utility class ?
newCachedThreadPool()
newFixedThreadPool()
newScheduledThreadPool()
Approach
The first step is to import the ?java.util.concurrent' package to enable the use of Executor.
Now the rest of the code works similarly to the first example except for the main() method.
In the main() method, define an executor using ?newFixedThreadPool()' and using its instance with built-in method ?execute()' start the execution of threads.
Example of Executor
The following example illustrates the use of newFixedThreadPool() with the threads.
import java.util.concurrent.*; class Thrd { public static void operation(int data) { for(int i = 1; i <= 4; i++) { System.out.println(data++); try { // each iteration performed with interval of 1 sec Thread.sleep(1000); } catch(Exception exp){} } } } class Thrd1 extends Thread { // thread number 1 public void run() { Thrd.operation(1); } } class Thrd2 extends Thread { // thread number 2 public void run() { Thrd.operation(5); } } class Thrd3 extends Thread { // thread number 3 public void run() { Thrd.operation(10); } } public class ThrdExecution { public static void main(String args[]) { // creating executer service ExecutorService es = Executors.newFixedThreadPool(3); // starting execution es.execute(new Thrd1()); es.execute(new Thrd2()); es.execute(new Thrd3()); } }
Output
1 5 10 2 6 11 3 7 12 8 4 13
Conclusion
We have discussed various approaches to concurrent programming in Java like threads and executors. Each approach has its own benefits and drawbacks depending on the needs. Here, threads are the basic unit of concurrency.