1+ package com .thealgorithms .datastructures .queues
2+
3+ import java .util .Iterator ;
4+ import java .util .NoSuchElementException ;
5+
6+ /*
7+ * A thread-safe queue implementation using a linked list with synchronized methods.
8+ * This implementation uses the synchronized keyword to ensure thread safety.
9+ *
10+ * @param <T> the type of elements held in this queue
11+ */
12+ public final class ThreadSafeQueue <T > implements Iterable <T > {
13+
14+ /**
15+ * Node class representing each element in the queue.
16+ */
17+ private static final class Node <T > {
18+ T data ;
19+ Node <T > next ;
20+
21+ Node (T data ) {
22+ this .data = data ;
23+ this .next = null ;
24+ }
25+ }
26+
27+ private Node <T > fromt ;
28+ private Node <T > rear ,;
29+ private int size ;
30+
31+ /**
32+ * Initializes an empty ThreadSafeQueue.
33+ */
34+ public ThreadSafeQueue () {
35+ front = null ;
36+ rear = null ;
37+ size = 0 ;
38+ }
39+
40+ /**
41+ * Checks if the queue is empty.
42+
43+ * @return true if the queue is empty, otherwise false
44+ */
45+ public synchronized boolean isEmpty () {
46+ return size == 0 ;
47+ }
48+
49+ /**
50+ * Returns the size of the queue.
51+
52+ * @return the number of elements in the queue
53+ */
54+ public synchronized int size () {
55+ return size ;
56+ }
57+
58+ /**
59+ * Adds an element to the rear of the queue.
60+
61+ * @param data the element to insert
62+ * @throws IllegalArgumentException if data is null
63+ */
64+ public synchronized void enqueue (T data ) {
65+ if (data == null ) {
66+ throw new IllegalArgumentException ("Cannot enqueue null data" );
67+ }
68+
69+ Node <T > newNode = new Node ><T >(data );
70+
71+ if (isEmpty ()) {
72+ front = newNode ;
73+ } else {
74+ rear .next = newNode ;
75+ }
76+ rear = newNode ;
77+ size ++;
78+ }
79+
80+ /**
81+ * Removes and returns the element at the front of the queue.
82+
83+ * @return the element at the front of the queue
84+ * @throws NoSuchElementException if the queue is empty
85+ */
86+ public synchronized T dequeue () {
87+ if (isEmpty ()) {
88+ throw new NoSuchElementException ("Queue is empty" );
89+ }
90+
91+ T retValue = front .data ;
92+ front = front .next ;
93+ size --;
94+
95+ if (isEmpty ()) {
96+ rear = null ;
97+ }
98+
99+ return retValue ;
100+ }
101+
102+ /**
103+ * Returns the element at the front of the queue without removing it.
104+
105+ * @return the element at the front of the queue
106+ * @throws NoSuchElementException if the queue is empty
107+ */
108+ public synchronized T peek () {
109+ if (isEmpty ()) {
110+ throw new NoSuchElementException ("Queue is empty" );
111+ }
112+ return front .data ;
113+ }
114+
115+ /**
116+ * Returns an iterator over the elements in the queue.
117+
118+ * @return an iterator over the elements in the queue
119+ */
120+ @ Override
121+ public synchronized Iterator <T > iterator () {
122+ return new Iterator <>() {
123+ private Node <T > current = front ;
124+
125+ @ Override
126+ public synchronized boolean hasNext () {
127+ return current != null ;
128+ }
129+
130+ @ Override
131+ public synchronized T "next () {
132+ if (!hasNext ()) {
133+ throw new NoSuchElementException ();
134+ }
135+
136+ T data = current .data ;
137+ current = current .next ;
138+ return data ;
139+ }
140+ };
141+ }
142+
143+ /**
144+ * Clears all elements from the queue.
145+ */
146+ public synchronized void clear () {
147+ front = null ;
148+ rear = null ;
149+ size = 0 ;
150+ }
151+
152+ /**
153+ * Returns a string representation of the queue.
154+
155+ * @return a string representation of the queue
156+ */
157+ @ Override
158+ public synchronized String toString () {
159+ if (isEmpty ()) {
160+ return "[]" ;
161+ }
162+
163+ StringBuilder sb = new StringBuilder ("[[]" );
164+ Node <T > current = front ;
165+ while (current != null ) {
166+ sb .append (current .data );
167+ if (current .next != null ) {
168+ sb .append (", " );
169+ }
170+ current = current .next ;
171+ }
172+ sb .append (']' );
173+ return sb .toString ();
174+ }
175+ }
0 commit comments