Hello friends, we meet again here today on our journey to Java. Before we
continue forward, let me inform you guys that today's topic is in continuation
of our Java Deque topic. If any of you guys have not read the
Java Deque tutorial, go ahead and read that one first. Though there is no such limitation of this
article, it is recommended to have gone through the basics of Deque and our
previous post. So, I guess now we will continue our Deque topic and today we
will discuss something very interesting. Today we are gonna jump into the
advanced topic of Deque and how we can leverage the functionality Java has
provided for a better and more robust application building.
So, as in our previous post, we discussed Deque and how we can utilize them in
Java. But, let's have a small summary/recap so that we start with a fresh
state.
Deque throws ConcurrentModificationException if multiple threads try to access deque at the same time. To illustrate more on Deque's limitation and see the exception, let us write a code together for demonstrating this.
Deque advantages and functionality:
- Deque is a double-ended queue in which we can add/delete elements from both ends.
- A Deque can be implemented using a doubly-linked list/ linked list in Java.
- Deque can be used in scenarios like designing a ticket counter (detailed explanation done in the previous article).
Deque limitations:
Considering a multi-threaded scenario, Deque's have a limitation. Deque can't handle multiple threads.Deque throws ConcurrentModificationException if multiple threads try to access deque at the same time. To illustrate more on Deque's limitation and see the exception, let us write a code together for demonstrating this.
Deque limitation code:
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
public class DequeDemo extends Thread{
public static Deque<Integer> deque;
public static void main(String[] args) throws InterruptedException {
deque = new LinkedList<>();
//add at last
deque.add(1);
//deque : 1
//add at first
deque.addFirst(3);
//deque : 3 -> 1
//add at last
deque.addLast(2);
//deque: 3 -> 1 -> 2
//add at last
deque.add(4);
//deque : 3 -> 1 -> 2 -> 4
//remove at first
deque.removeFirst();
//deque : 1 -> 2 -> 4
deque.forEach(a -> System.out.print(a+"->"));
System.out.println();
DequeDemo myClass = new DequeDemo();
Thread first = new Thread(myClass, "First thread") {
@Override
public void run() {
System.out.println("this is first thread. starting");
for(int i:deque) {
System.out.print(i+"->");
}
System.out.println();
System.out.println("First thread ending");
}
};
Thread second = new Thread(myClass, "Second thread") {
@Override
public void run() {
System.out.println("this is second thread. starting");
deque.addFirst(9);
System.out.println("This is thread 2. value added at front :"+9);
}
};
first.start();
second.start();
Thread.sleep(1000);
System.out.println();
deque.forEach(a -> System.out.print(a+"->"));
System.out.println();
}
}
Deque limitation output:As we can observe the output, it throws a java.util.ConcurrentModificationException. This is because, in our code, there are 2 threads operating at the same time on our Deque.Thread 1 is traversing the Deque, and Thread 2 adds/inserts an element at the front of deque. Due to this, the output of Thread 1 will be inconsistent. Thus, java throws an exception and notifies that concurrent modifications are happening in the code.So, is this it? How can we make it thread safe? No worries my friends, Java is here for our help!Java provides an inbuilt solution for our problem. So, what's the wait? Let's start!
What is Blocking Deque in Java?
BlockingDeque is a deque that is thread-safe. Multiple threads can work on the same data structure without any error or exception. But, a BlockingDeque has a lock on the data structure level.This means, whenever any operation is performed on BlockingDeque, a lock is obtained and only the thread that has a lock can modify/work on deque.This is very inefficient as if there are 500 threads waiting to work on deque, each has to work one-by-one after obtaining the lock.BlockingDeque can be declared as below:BlockingDeque<Integer> deque = new LinkedBlockingDeque<>();Let’s understand a sample program utilizing BlockingDeque. We will write the exact same code that gave us Exception in deque and check what happens.BlockingDeque code Example
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
public class DequeDemo extends Thread{
public static BlockingDeque<Integer> deque;
public static void main(String[] args) throws InterruptedException {
deque = new LinkedBlockingDeque<>();
//add at last
deque.add(1);
//deque : 1
//add at first
deque.addFirst(3);
//deque : 3 -> 1
//add at last
deque.addLast(2);
//deque: 3 -> 1 -> 2
//add at last
deque.add(4);
//deque : 3 -> 1 -> 2 -> 4
//remove at first
deque.removeFirst();
//deque : 1 -> 2 -> 4
deque.forEach(a -> System.out.print(a+"->"));
System.out.println();
DequeDemo myClass = new DequeDemo();
Thread first = new Thread(myClass, "First thread") {
@Override
public void run() {
System.out.println("this is first thread. starting");
for(int i:deque) {
System.out.print(i+"->");
}
System.out.println();
System.out.println("First thread ending");
}
};
Thread second = new Thread(myClass, "Second thread") {
@Override
public void run() {
System.out.println("this is second thread. starting");
deque.addFirst(9);
System.out.println("This is thread 2. value added at front :"+9);
}
};
first.start();
second.start();
Thread.sleep(1000);
System.out.println();
deque.forEach(a -> System.out.print(a+"->"));
System.out.println();
}
}Output:After observing the output, we now know that it is thread safe. But how does Java do this? What happens behind the door?Java puts a data structure level lock for any operation on Blocking Deque. This means, in our code, whichever thread first started to work on our deque, acquired it's lock. After finishing it's work, it released the lock and other thread now can take this lock. As simple as that. But there are few points to keep in mind.
Blocking deque important points:
As previously noted, Java's BlockingDeque provides support for blocking activities, however blocking methods are divided into four categories based on how they handle actions that cannot be completed immediately but may be completed later:
- Throws Exception : Methods that fall into this category will throw an exception if they are blocked.
- Return a special value : If a wait is required, this type of procedure will return a value, such as false.
- Blocks : These techniques will wait for space to become available if required.
- Times out : This sort of technique will only block for a certain amount of time before giving up.
Limitation:
Blocking Deque puts a Structure level lock which means, all threads need to work sequentially on the Deque which is not at all efficient. Consider 3 writers and 300 readers, all would work in sequential way when it could be more efficient considering concurrency.That's all about what is BlokcingDeque in Java and how and when to use it. This is one of the utility classes from Java's Concurrent Collection pacakge and can be very useful for writing thread-safe, concurrent code. Along with BlockcingQueue and ConcurrnetHashMap, BlockingDeque is three classes from java.util.concurrent package which every Java programmer should learn and use.Other Java Collection Articles you may like
- 7 Best Courses to learn Java Collections and Stream API
- 21 skills Java Programmer Should Learn
- How to use WeakHashMap in Java
- 10 Frameworks Java developers should learn
- How to compare objects by multiple fields
- Difference between HashMap and ArrayList in Java
- Comparator Comparing and thenComparing example
- When to use Map, List, and Set collection in Java
- 10 Advanced Core Java Courses for Programmers
- Difference between HashMap and HashSet in Java
- 8 Best Java Functional Programming Courses
- Difference between IdentityHashMap and HashMap in Java
- 50+ Java Collection Interview Questions with Answers
- Top 5 Courses to become a Fullstack Java Developer
Thanks for reading this article if you find these Java Deque examples useful then please share them with your friends and colleagues. If you have any questions or feedback then please drop me a note.P. S. - If you are new to Java and looking for a free course to learn Java in a structured way then you can also check this Java Tutorial for Complete Beginners(FREE) course on Udemy. It's fully online, free and more than 1.4 million developers have joined this course. You just need a free Udemy account to join the course.
No comments:
Post a Comment
Feel free to comment, ask questions if you have any doubt.