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();
    }
}
