package java.lang.ref;

import ej.annotation.Nullable;

/**
 * Reference queues, to which registered reference objects are appended by the garbage collector
 * after the appropriate reachability changes are detected.
 * 
 * @param <T> the type of the referenced objects
 */
public class ReferenceQueue<T> {

	/**
	 * Constructs a new reference-object queue.
	 */
	public ReferenceQueue() {
		throw new RuntimeException();
	}

	/**
	 * Polls this queue to see if a reference object is available. If one is available without further
	 * delay then it is removed from the queue and returned. Otherwise this method immediately returns
	 * <code>null</code>.
	 *
	 * @return A reference object, if one was immediately available, otherwise <code>null</code>
	 */
	@Nullable
	public Reference<? extends T> poll() {
		throw new RuntimeException();
	}

	/**
	 * Removes the next reference object in this queue, blocking until one becomes available.
	 *
	 * @return A reference object, blocking until one becomes available
	 * @throws InterruptedException
	 *         If the wait is interrupted
	 */
	public Reference<? extends T> remove() throws InterruptedException {
		throw new RuntimeException();
	}

	/**
	 * Removes the next reference object in this queue, blocking until either one becomes available or
	 * the given timeout period expires.
	 *
	 * <p>
	 * This method does not offer real-time guarantees: It schedules the timeout as if by invoking the
	 * {@link Object#wait(long)} method.
	 *
	 * @param timeout
	 *        If positive, block for up to <code>timeout</code> milliseconds while waiting for a
	 *        reference to be added to this queue. If zero, block indefinitely.
	 *
	 * @return A reference object, if one was available within the specified timeout period, otherwise
	 *         <code>null</code>
	 *
	 * @throws IllegalArgumentException
	 *         If the value of the timeout argument is negative
	 *
	 * @throws InterruptedException
	 *         If the timeout wait is interrupted
	 */
	@Nullable
	public Reference<? extends T> remove(long timeout) throws IllegalArgumentException, InterruptedException {
		throw new RuntimeException();
	}

}
