Open In App

How to Handle Concurrent Access and Modification of a PriorityQueue in Java?

In Java, PriorityQueue is a class that implements a priority queue based on the priority heap. While PriorityQueue provides efficient operations for the adding and removing elements and it is not inherently thread-safe. Concurrent access and modification of the PriorityQueue can lead to unexpected behavior or runtime exceptions in the multi-threaded environment. To handle concurrent access and modification safely synchronization mechanisms need to be employed.

How to Handle Concurrent Access and Modification of a PriorityQueue in Java

To handle concurrent access and modification of the PriorityQueue in Java. The synchronization can be achieved using the various methods:

1. Synchronized Methods

We can synchronize the methods that access or modify the PriorityQueue to ensure that only one thread can execute them at a time. This can be achieved by using the synchronized keyword.

Example of Synchronized Methods:

public synchronized void addElement(Object element) { 
// Add element to the PriorityQueue
}

public synchronized Object removeElement() {
// Remove and return element from the PriorityQueue
}

2. Explicit Locks

Java provides the Lock interface and its implementations for the explicit locking mechanisms. We can acquire and release locks around critical sections of the code that access or modify the PriorityQueue.

Example of Explicit Locks:

private final Lock lock = new ReentrantLock(); 
public void addElement(Object element) {
lock.lock();

try {
// Add element to the PriorityQueue
}
finally{
lock.unlock();
}
}

public Object removeElement() {
lock.lock();
try {
// Remove and return element from the PriorityQueue
}
finally {
lock.unlock();
}
}

3. Thread-Safe Wrapper

The Another approach is to the use thread-safe wrappers provided by Collections class. For example : we can use Collections.synchronizedPriorityQueue() method to the obtain a synchronized wrapper around the original PriorityQueue.

Thread-Safe Wrapper Example:

PriorityQueue<Object> priorityQueue = new PriorityQueue<>();
Collection<Object> synchronizedQueue = Collections.synchronizedCollection(priorityQueue);

Program to Handle Concurrent Access and Modification of a PriorityQueue

// Java Program to Handle Concurrent Access
// and Modification of a PriorityQueue
import java.util.Collections;
import java.util.PriorityQueue;

public class GFG {
    // PriorityQueue to store elements
    private final PriorityQueue<Integer> priorityQueue;

    // Constructor to initialize the PriorityQueue
    public GFG() {
        priorityQueue = new PriorityQueue<>();
    }

    // Method to add an element to the PriorityQueue
    public void addElement(int element) {
        // Synchronize access to the PriorityQueue
          // to handle concurrent modification
        synchronized (priorityQueue) {
            priorityQueue.add(element);
        }
    }

    // Method to remove an element from the PriorityQueue
    public int removeElement() {
        // Synchronize access to the PriorityQueue
          // to handle concurrent modification
        synchronized (priorityQueue) {
            return priorityQueue.poll();
        }
    }

    // Main method to demonstrate the usage of the GFG class
    public static void main(String[] args) {
        // Create an instance of the GFG class
        GFG example = new GFG();
        
        // Add elements to the PriorityQueue
        example.addElement(5);
        example.addElement(3);
        example.addElement(8);
        
        // Remove an element from the PriorityQueue and print it
        System.out.println("Removed element: " + example.removeElement());
    }
}

Output :

Removed element: 3
Article Tags :