import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; public class TestIsEnqueued { private static final long ENQUEUE_CHECK_DELAY = 500; // 1/2 sec check period private static final long ENQUEUE_TIMEOUT = 30000; // 30 sec timeout private static final ReferenceQueue q = new ReferenceQueue<>(); private static Object o = new Object(); private static final PhantomReference r = new PhantomReference<>(o, q); public static void main(String[] args) throws Throwable { // delete reference to o, and verify r gets notified. o = null; System.gc(); // wait for enqueue, as it might not be instantaneous. for (long i = 0; i < ENQUEUE_TIMEOUT; i += ENQUEUE_CHECK_DELAY) { Thread.sleep(ENQUEUE_CHECK_DELAY); if (r.isEnqueued()) break; } if (!r.isEnqueued()) { throw new RuntimeException("reference not notified"); } // now remove r from q, and test r's isEnqueued() state. Object qr = q.remove(ENQUEUE_TIMEOUT); if (qr == null) { throw new RuntimeException("empty queue"); } else if (qr != r) { throw new RuntimeException("unexpected queue entry"); } else if (!r.isEnqueued()) { throw new RuntimeException( "TEST FAILED: reference transitioned to not enqueued"); } } }