--- old/test/java/lang/ref/ReferenceEnqueue.java 2017-02-24 17:13:34.000000000 -0800 +++ new/test/java/lang/ref/ReferenceEnqueue.java 2017-02-24 17:13:34.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,17 +22,24 @@ */ /* @test - * @bug 4268317 8132306 + * @bug 4268317 8132306 8175797 * @summary Test if Reference.enqueue() works properly with GC + * @run main ReferenceEnqueue + * @run main/othervm -Djdk.ref.disableClearAndEnqueue=true ReferenceEnqueue + * @run main/othervm -Djava.security.manager ReferenceEnqueue */ import java.lang.ref.*; +import java.util.ArrayList; +import java.util.List; public class ReferenceEnqueue { public static void main(String args[]) throws Exception { - for (int i=0; i < 5; i++) + for (int i=0; i < 5; i++) { new WeakRef().run(); + new ExplicitEnqueue().run(); + } System.out.println("Test passed."); } @@ -76,4 +83,50 @@ } } } + + static class ExplicitEnqueue { + final ReferenceQueue queue = new ReferenceQueue<>(); + final List> refs = new ArrayList<>(); + final int iterations = 1000; + final boolean disableClearAndEnqueue = + Boolean.parseBoolean("jdk.ref.disableClearAndEnqueue"); + + ExplicitEnqueue() { + this.refs.add(new SoftReference<>(new Object(), queue)); + this.refs.add(new WeakReference<>(new Object(), queue)); + this.refs.add(new PhantomReference<>(new Object(), queue)); + } + + void run() throws InterruptedException { + for (Reference ref : refs) { + if (ref.enqueue() == false) { + throw new RuntimeException("Error: enqueue failed"); + } + if (disableClearAndEnqueue && ref.get() == null) { + throw new RuntimeException("Error: clearing should be disabled"); + } + if (!disableClearAndEnqueue && ref.get() != null) { + throw new RuntimeException("Error: referent must be cleared"); + } + } + + System.gc(); + for (int i = 0; refs.size() > 0 && i < iterations; i++) { + Reference ref = (Reference)queue.poll(); + if (ref == null) { + System.gc(); + Thread.sleep(100); + continue; + } + + if (refs.remove(ref) == false) { + throw new RuntimeException("Error: unknown reference " + ref); + } + } + + if (!refs.isEmpty()) { + throw new RuntimeException("Error: not all references are removed"); + } + } + } }