| /* |
| * Copyright (c) 1997, 1998, 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 |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* @test |
| * @summary Basic functional test of reference objects |
| * @author Mark Reinhold |
| */ |
| |
| |
| import java.lang.ref.*; |
| import java.util.Vector; |
| |
| |
| public class Basic { |
| |
| static ReferenceQueue q = new ReferenceQueue(); |
| static ReferenceQueue q2 = new ReferenceQueue(); |
| static Reference rw, rw2, rp, rp2; |
| static Vector keep = new Vector(); |
| static boolean finalized = false; |
| |
| public static class ClearFinalizerThread { |
| protected void finalize() { |
| System.err.println("Cleared finalizer thread"); |
| } |
| }; |
| |
| protected void finalize() { |
| Basic.finalized = true; |
| System.err.println("Finalized " + this); |
| } |
| |
| public static class Sub { }; |
| |
| Object sub = new Sub(); |
| |
| static void fork(Runnable proc) throws InterruptedException { |
| Thread t = new Thread(proc); |
| t.start(); |
| t.join(); |
| } |
| |
| static void showReferences() throws InterruptedException { |
| fork(new Runnable() { |
| public void run() { |
| System.err.println("References: W " + rw.get() |
| + ", W2 " + rw2.get() |
| + ", P " + rp.get() |
| + ", P2 " + rp2.get()); |
| } |
| }); |
| } |
| |
| static void createNoise() throws InterruptedException { |
| fork(new Runnable() { |
| public void run() { |
| keep.addElement(new PhantomReference(new Object(), q2)); |
| } |
| }); |
| } |
| |
| |
| public static void main(String[] args) throws Exception { |
| |
| fork(new Runnable() { |
| public void run() { |
| Basic s = new Basic(); |
| rw = new WeakReference(s, q); |
| rw2 = new WeakReference(s); |
| rp = new PhantomReference(s, q); |
| rp2 = new PhantomReference(s.sub, q); |
| s = null; |
| } |
| }); |
| |
| showReferences(); |
| |
| int ndq = 0; |
| boolean prevFinalized = false; |
| outer: |
| for (int i = 1;; i++) { |
| Reference r; |
| |
| createNoise(); |
| System.err.println("GC " + i); |
| Thread.sleep(10); |
| System.gc(); |
| |
| showReferences(); |
| while ((r = q2.poll()) != null) { |
| System.err.println("Noise " + r); |
| } |
| |
| /* Cause a dummy object to be finalized, since the finalizer thread |
| might retain a reference to the Basic instance after it's been |
| finalized (this happens with java_g) */ |
| if (Basic.finalized && !prevFinalized) { |
| fork(new Runnable() { |
| public void run() { |
| new ClearFinalizerThread(); |
| }}); |
| prevFinalized = true; |
| } |
| |
| while ((r = q.poll()) != null) { |
| ndq++; |
| if (r != null) { |
| System.err.println("Dequeued " + r); |
| if (ndq == 3) break outer; |
| } |
| } |
| |
| if (i >= 10) break; |
| |
| } |
| |
| if (ndq != 3) { |
| throw new Exception("Expected to dequeue 3 reference objects," |
| + " but only got " + ndq); |
| } |
| |
| if (! Basic.finalized) { |
| throw new Exception("Test object not finalized"); |
| } |
| |
| } |
| |
| } |