001/* 002 * %W% %E% 003 * 004 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 005 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 006 */ 007 008package sun.misc; 009 010import java.util.Enumeration; 011import java.util.NoSuchElementException; 012 013/** 014 * Queue: implements a simple queue mechanism. Allows for enumeration of the 015 * elements. 016 * 017 * @version %I%, %G% 018 * @author Herb Jellinek 019 */ 020 021public class Queue { 022 023 int length = 0; 024 025 QueueElement head = null; 026 QueueElement tail = null; 027 028 public Queue() { 029 } 030 031 /** 032 * Enqueue an object. 033 */ 034 public synchronized void enqueue(Object obj) { 035 036 QueueElement newElt = new QueueElement(obj); 037 038 if (head == null) { 039 head = newElt; 040 tail = newElt; 041 length = 1; 042 } else { 043 newElt.next = head; 044 head.prev = newElt; 045 head = newElt; 046 length++; 047 } 048 notify(); 049 } 050 051 /** 052 * Dequeue the oldest object on the queue. Will wait indefinitely. 053 * 054 * @return the oldest object on the queue. 055 * @exception java.lang.InterruptedException if any thread has 056 * interrupted this thread. 057 */ 058 public Object dequeue() throws InterruptedException { 059 return dequeue(0L); 060 } 061 062 /** 063 * Dequeue the oldest object on the queue. 064 * @param timeOut the number of milliseconds to wait for something 065 * to arrive. 066 * 067 * @return the oldest object on the queue. 068 * @exception java.lang.InterruptedException if any thread has 069 * interrupted this thread. 070 */ 071 public synchronized Object dequeue(long timeOut) 072 throws InterruptedException { 073 074 while (tail == null) { 075 wait(timeOut); 076 } 077 QueueElement elt = tail; 078 tail = elt.prev; 079 if (tail == null) { 080 head = null; 081 } else { 082 tail.next = null; 083 } 084 length--; 085 return elt.obj; 086 } 087 088 /** 089 * Is the queue empty? 090 * @return true if the queue is empty. 091 */ 092 public synchronized boolean isEmpty() { 093 return (tail == null); 094 } 095 096 /** 097 * Returns an enumeration of the elements in Last-In, First-Out 098 * order. Use the Enumeration methods on the returned object to 099 * fetch the elements sequentially. 100 */ 101 public final synchronized Enumeration elements() { 102 return new LIFOQueueEnumerator(this); 103 } 104 105 /** 106 * Returns an enumeration of the elements in First-In, First-Out 107 * order. Use the Enumeration methods on the returned object to 108 * fetch the elements sequentially. 109 */ 110 public final synchronized Enumeration reverseElements() { 111 return new FIFOQueueEnumerator(this); 112 } 113 114 public synchronized void dump(String msg) { 115 System.err.println(">> "+msg); 116 System.err.println("["+length+" elt(s); head = "+ 117 (head == null ? "null" : (head.obj)+"")+ 118 " tail = "+(tail == null ? "null" : (tail.obj)+"")); 119 QueueElement cursor = head; 120 QueueElement last = null; 121 while (cursor != null) { 122 System.err.println(" "+cursor); 123 last = cursor; 124 cursor = cursor.next; 125 } 126 if (last != tail) { 127 System.err.println(" tail != last: "+tail+", "+last); 128 } 129 System.err.println("]"); 130 } 131} 132 133final class FIFOQueueEnumerator implements Enumeration { 134 Queue queue; 135 QueueElement cursor; 136 137 FIFOQueueEnumerator(Queue q) { 138 queue = q; 139 cursor = q.tail; 140 } 141 142 public boolean hasMoreElements() { 143 return (cursor != null); 144 } 145 146 public Object nextElement() { 147 synchronized (queue) { 148 if (cursor != null) { 149 QueueElement result = cursor; 150 cursor = cursor.prev; 151 return result.obj; 152 } 153 } 154 throw new NoSuchElementException("FIFOQueueEnumerator"); 155 } 156} 157 158final class LIFOQueueEnumerator implements Enumeration { 159 Queue queue; 160 QueueElement cursor; 161 162 LIFOQueueEnumerator(Queue q) { 163 queue = q; 164 cursor = q.head; 165 } 166 167 public boolean hasMoreElements() { 168 return (cursor != null); 169 } 170 171 public Object nextElement() { 172 synchronized (queue) { 173 if (cursor != null) { 174 QueueElement result = cursor; 175 cursor = cursor.next; 176 return result.obj; 177 } 178 } 179 throw new NoSuchElementException("LIFOQueueEnumerator"); 180 } 181} 182 183class QueueElement { 184 QueueElement next = null; 185 QueueElement prev = null; 186 187 Object obj = null; 188 189 QueueElement(Object obj) { 190 this.obj = obj; 191 } 192 193 public String toString() { 194 return "QueueElement[obj="+obj+(prev == null ? " null" : " prev")+ 195 (next == null ? " null" : " next")+"]"; 196 } 197} 198