Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package com.thealgorithms.datastructures.queues
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A semicolon (;) is missing at the end.


import java.util.Iterator;
import java.util.NoSuchElementException;

/*
* A thread-safe queue implementation using a linked list with synchronized methods.
* This implementation uses the synchronized keyword to ensure thread safety.
*
* @param <T> the type of elements held in this queue
*/
public final class ThreadSafeQueue<T> implements Iterable<T> {

/**
* Node class representing each element in the queue.
*/
private static final class Node<T> {
T data;
Node<T> next;

Node(T data) {
this.data = data;
this.next = null;
}
}

private Node<T> fromt;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean 'front' instead of 'fromt'?

private Node<T> rear,;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s an extra comma after rear.

private int size;

/**
* Initializes an empty ThreadSafeQueue.
*/
public ThreadSafeQueue() {
front = null;
rear = null;
size = 0;
}

/**
* Checks if the queue is empty.

* @return true if the queue is empty, otherwise false
*/
public synchronized boolean isEmpty() {
return size == 0;
}

/**
* Returns the size of the queue.

* @return the number of elements in the queue
*/
public synchronized int size() {
return size;
}

/**
* Adds an element to the rear of the queue.

* @param data the element to insert
* @throws IllegalArgumentException if data is null
*/
public synchronized void enqueue(T data) {
if (data == null) {
throw new IllegalArgumentException("Cannot enqueue null data");
}

Node<T> newNode = new Node><T>(data);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s an extra > here.
Fix: Node newNode = new Node<>(data);


if (isEmpty()) {
front = newNode;
} else {
rear.next = newNode;
}
rear = newNode;
size++;
}

/**
* Removes and returns the element at the front of the queue.

* @return the element at the front of the queue
* @throws NoSuchElementException if the queue is empty
*/
public synchronized T dequeue() {
if (isEmpty()) {
throw new NoSuchElementException("Queue is empty");
}

T retValue = front.data;
front = front.next;
size--;

if (isEmpty()) {
rear = null;
}

return retValue;
}

/**
* Returns the element at the front of the queue without removing it.

* @return the element at the front of the queue
* @throws NoSuchElementException if the queue is empty
*/
public synchronized T peek() {
if (isEmpty()) {
throw new NoSuchElementException("Queue is empty");
}
return front.data;
}

/**
* Returns an iterator over the elements in the queue.

* @return an iterator over the elements in the queue
*/
@Override
public synchronized Iterator<T> iterator() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iterator is not fully thread-safe; it only captures the current state of front and may behave inconsistently under concurrent modifications.

return new Iterator<>() {
private Node<T> current = front;

@Override
public synchronized boolean hasNext() {
return current != null;
}

@Override
public synchronized T"next() {
Copy link
Copy Markdown
Contributor

@felseje felseje Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the "
Fix: public synchronized T next() {

if (!hasNext()) {
throw new NoSuchElementException();
}

T data = current.data;
current = current.next;
return data;
}
};
}

/**
* Clears all elements from the queue.
*/
public synchronized void clear() {
front = null;
rear = null;
size = 0;
}

/**
* Returns a string representation of the queue.

* @return a string representation of the queue
*/
@Override
public synchronized String toString() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling isEmpty() inside other synchronized methods is redundant, since those methods already hold the lock. This doesn’t cause correctness issues, but it adds unnecessary synchronization overhead.

if (isEmpty()) {
return "[]";
}

StringBuilder sb = new StringBuilder("[[]");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean "StringBuilder sb = new StringBuilder("[");" ?

Node<T> current = front;
while (current != null) {
sb.append(current.data);
if (current.next != null) {
sb.append(", ");
}
current = current.next;
}
sb.append(']');
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,18 @@ class BinarySearch implements SearchAlgorithm {
*/
@Override
public <T extends Comparable<T>> int find(T[] array, T key) {
// Handle edge case: empty array
// Handle edge case: null or empty array
if (array == null || array.length == 0) {
return -1;
}

// Handle edge case: null key
// Searching for null in an array of Comparables is undefined behavior
// Return -1 to indicate not found rather than throwing NPE
if (key == null) {
return -1;
}

// Delegate to the core search implementation
return search(array, key, 0, array.length - 1);
}
Expand Down
Loading