Thread safe queue manager

Implement a thread-safe Java class QueueManager that manages multiple named queues. The class must support concurrent access from multiple threads.

Required Methods

Your QueueManager class must implement the following methods:

add(String queueName, String... items)

Adds one or more items to the specified queue. All items are stored as strings.

If the queue does not exist, create it automatically. Example: add("master", "2", "10.2", "Text") creates queue "master" (if it doesn't exist) and adds three items.

pop(String queueName)

Removes and returns the first item from the queue (FIFO - first in, first out).

Throws QueueEmptyException if the queue is empty. Throws QueueDoesNotExistException if the queue does not exist.

clear(String queueName)

Removes all items from the queue, making it empty. The queue object itself remains.

Throws QueueDoesNotExistException if the queue does not exist.

getQueueContents(String queueName)

Returns a list of all items in the queue in FIFO order (first item added appears first).

Throws QueueDoesNotExistException if the queue does not exist.

getAllQueueNames()

Returns a collection of all queue names currently managed.

sortQueue(String queueName)

Sorts the items in the specified queue alphabetically (as strings).

Throws QueueDoesNotExistException if the queue does not exist.

deleteQueue(String queueName)

Removes the queue entirely from the manager.

Throws QueueDoesNotExistException if the queue does not exist. Thread-Safety Requirements


CRITICAL: Your implementation must be thread-safe.

REQUIRED: Implement "fine-grained thread-safety" so that:

Operations on different queues can proceed concurrently without blocking each other Operations on the same queue are properly synchronized Creating new queues is thread-safe Reading the list of all queues is thread-safe Example scenario that must work concurrently:

  • Thread 1 adds items to queue "A"

  • Thread 2 adds items to queue "B"

  • Thread 3 pops from queue "C"

These operations should NOT block each other since they operate on different queues.

Custom Exceptions

Create the following custom exceptions:

  • QueueEmptyException - thrown when attempting to pop from an empty queue

  • QueueDoesNotExistException - thrown when referencing a non-existent queue

Implementation Tips

Consider using:

  • ConcurrentHashMap for storing queues

  • Per-queue locks (e.g., a lock object associated with each queue)

  • Proper synchronization for queue creation

  • Defensive copying when returning queue contents