What is Concurrency in Java?
In today’s world, everything is developing rapidly. There is always a scope for improvement in each and everything. So is the case with our programming language. Today, with our modern technologies, we expect things to be done easily and rapidly. For doing multiple things at the same time or for doing several things simultaneously, the concept of concurrency arose. So what is concurrency, its use, why is this really needed, and many more? We will try to touch on such questions and answer them in this article one by one. So let us bring our discussion to a very basic common section: the definition of concurrency. In this topic, we are going to learn about. What concurrency is in Java.
Definition of concurrency?
So what concurrency, actually is? Well, to answer that, let us take a common scenario. Suppose while reading this article, you’re trying to do multiple things simultaneously; maybe you are trying to make a note also, or maybe you are trying to understand it or thinking some stuff. So in simple words, you are trying to do multiple things in parallel. This is what concurrency means. Concurrency is simply executing multiple tasks in parallel to each other. We will discuss concurrency in this article in the scope of Java as a programming language.
Actually, in Java or in general in any programming language, it is the thread that is responsible for carrying concurrency. The basic role of these threads is to facilitate the parallel execution of tasks. Meanwhile, let us have a basic definition of thread.
So what is a Thread?
A thread is a lightweight process with its own call stack. However, a thread can access shared data from other threads executing under the same process. We can use many threads within a Java application to achieve parallel processing or concurrency.
Now let us move to our next topic, which is,
Concurrency in Java definition?
So, all OOP language has a threading concept in Java or any other programming language like C#. In Java, we have different processes which run by making different threads to achieve concurrency.
So after this simple definition, let us discuss our new topic, which is:
What makes java applications concurrent?
The first class, which one needs to make a java application concurrent, is java.lang.Thread class. java.lang.Thread class is responsible for all concurrency concepts in the Java programming language. After this, we have java.lang.Runnable interface to abstract the thread behavior out of the thread class.
Other classes in which we will need to build an advanced application will be used from the java.util.concurrent package added in Java 1.5.
Now with that, we have reached a new question which is:
Is Java Concurrency really that simple?
As it seems that implementing concurrency in Java is quite simple. However, it is really not so. Let us see to it.
Our above discussion generally gives the impression that concurrency is indeed a simple, good concept and quite easy to implement. Well, if we monitor it better and try to understand it, we find that it requires a good amount of understanding of basic concepts and a thorough understanding of what we need to achieve.
If we compare concurrent applications and single-threaded applications, we generally find that a concurrent application is complex in terms of design and understanding. Code executed by multiple threads requires special attention and resources for accessing shared data. Errors popping due to incorrect thread synchronization are hard to debug and fix. Also, in most of the scenarios, these bugs do not get identified in the initial phase; in fact, it is detected in prod mode, which is even harder to reproduce.
Apart from bugs and common defects, concurrent threads require more resources to run the application.
Problems and improvement in concurrency – Explanation with Example
So basically, there are two types of problems assigned due to concurrency. These problems can be broadly classified into two categories
- Thread interference errors
- Memory consistency errors
Let us understand each one by one
Thread interference errors – Let us understand with a simple example.
Suppose we have a counter function whose basic role is to increase the counter or count of a number. Now suppose we have two threads, thread A and thread B. Suppose thread A reads the initial value as 0. Now, the following steps run sequentially.
- Thread A reads the initial value as 0
- Thread B reads the initial value as 0
- Thread A increase value by 1. The new value is now 1
- Thread B also, in parallel, increases the value to 1.
- Thread A writes an updated value which is 1, into the memory cell
- Thread B also repeats the same step, which is written in the memory cell updated value of 1
So here the problem arises. Two threads A & B, execute the code twice, and the expected value is 2 but what is reflected is 1. This is the main problem that multiple threads could cause
How could this be solved?
Thread interference errors can be solved by synchronizing access to shared variables. We must keep in sync with the updated values between the shared data.
With this, let us look into the second type of error
Memory Consistency Errors
Memory inconsistency errors generally occur when different threads try to read or have inconsistent views on the same piece of data. This usually happens when the first thread updates some shared data, and this updated value is not propagated to second or different threads, and they read old data.
Let’s see why this happens.
Well, there could be many causes for this. Usually, the compiler generally does several optimizations to the application to improve performance. It may also update instruction sequences to optimize performance. Even generally, processors also try to optimize codes; for instance, a CPU might read the current value of a variable from cache memory or temporary register instead of main memory.
Concurrency is a very important feature of any OOP language. Threading allows us to execute multiple processes in parallel to each other. It helps us to execute our complex tasks faster. However, pros, concurrency has a few cons too. Using threading causes heavy usage of resources.
This has been a Guide to Concurrency in Java. Here we have discussed the Problems and Improvement in Concurrency, for example. You can also go through our other suggested articles to learn more –
- What is Multithreading in java?
- How to Connect Database in Java?
- What is Multithreading in java?
- What is J2EE?