class Queue {
        // The first and last elements in the queue
    Element head, tail;

    public synchronized void append(Element p) {
        if (tail == null)
            head = p;
        else
            tail.next = p;
        p.next = null;
        tail = p;
        notify();  // Let waiters know something arrived
    }

    public synchronized Element get() {
        try {
            while(head == null)
                wait();    // Wait for an element
        } catch (InterruptedException e) {
            return null;
        }

        Element p = head;  // Remember first element
        head = head.next;  // Remove it from the queue
        if (head == null)  // Check for an empty queue
            tail = null;
        return p;
    }
}