import java.util.*;
import java.util.concurrent.*;

public class UnlinkingNodesAndWeaklyConsistent {
    public static void main(String... args) {
        test(new LinkedBlockingQueue<Integer>());
        test(new LinkedTransferQueue<Integer>());
        test(new ConcurrentLinkedQueue<Integer>());
        test(new ConcurrentLinkedDeque<Integer>());
        test(new LinkedBlockingDeque<Integer>()); // does not work in its current form
        test(new ArrayBlockingQueue<Integer>(20)); // never continues output after clear()
    }

    private static void test(Queue<Integer> q) {
        System.out.println("Testing " + q.getClass().getSimpleName());
        Collections.addAll(q, 1, 2, 3, 4, 5, 6);

        System.out.println("clear()");
        Iterator<Integer> it = q.iterator();
        System.out.println(it.next()); // 1
        System.out.println(it.next()); // 2
        q.clear();
        System.out.println(it.next()); // 3 - cached
        System.out.println(it.hasNext()); // false

        System.out.println("clear() and add()");
        Collections.addAll(q, 1, 2, 3, 4, 5, 6);
        it = q.iterator();
        System.out.println(it.next()); // 1
        System.out.println(it.next()); // 2
        q.clear();
        q.add(80);
        q.add(90);
        q.add(100);
        // preferred output: 3, 80, 90, 100
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        q.clear();

        System.out.println("while(poll() != null) and add()");
        Collections.addAll(q, 1, 2, 3, 4, 5, 6);
        it = q.iterator();
        System.out.println(it.next()); // 1
        System.out.println(it.next()); // 2
        while (q.poll() != null) ;
        q.add(80);
        q.add(90);
        q.add(100);
        // preferred output: 3, 80, 90, 100
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        System.out.println();
    }
}
