Skip to content

Commit 330d63d

Browse files
author
Poonam Bajaj
committed
8175797: (ref) Reference::enqueue method should clear the reference object before enqueuing
8178832: (ref) jdk.lang.ref.disableClearBeforeEnqueue property is ignored 8193780: (ref) Remove the undocumented "jdk.lang.ref.disableClearBeforeEnqueue" system property Reviewed-by: mchung, kbarrett, iris
1 parent ad6cdea commit 330d63d

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

jdk/src/share/classes/java/lang/ref/FinalReference.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -33,4 +33,9 @@ class FinalReference<T> extends Reference<T> {
3333
public FinalReference(T referent, ReferenceQueue<? super T> q) {
3434
super(referent, q);
3535
}
36+
37+
@Override
38+
public boolean enqueue() {
39+
throw new InternalError("should never reach here");
40+
}
3641
}

jdk/src/share/classes/java/lang/ref/Reference.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ public void clear() {
213213
this.referent = null;
214214
}
215215

216-
217216
/* -- Queue operations -- */
218217

219218
/**
@@ -230,8 +229,8 @@ public boolean isEnqueued() {
230229
}
231230

232231
/**
233-
* Adds this reference object to the queue with which it is registered,
234-
* if any.
232+
* Clears this reference object and adds it to the queue with which
233+
* it is registered, if any.
235234
*
236235
* <p> This method is invoked only by Java code; when the garbage collector
237236
* enqueues references it does so directly, without invoking this method.
@@ -241,10 +240,10 @@ public boolean isEnqueued() {
241240
* it was not registered with a queue when it was created
242241
*/
243242
public boolean enqueue() {
243+
this.referent = null;
244244
return this.queue.enqueue(this);
245245
}
246246

247-
248247
/* -- Constructors -- */
249248

250249
Reference(T referent) {
@@ -255,5 +254,4 @@ public boolean enqueue() {
255254
this.referent = referent;
256255
this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
257256
}
258-
259257
}

jdk/test/java/lang/ref/ReferenceEnqueue.java

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,17 +22,22 @@
2222
*/
2323

2424
/* @test
25-
* @bug 4268317
25+
* @bug 4268317 8175797
2626
* @summary Test if Reference.enqueue() works properly with GC
27+
* @run main ReferenceEnqueue
2728
*/
2829

2930
import java.lang.ref.*;
31+
import java.util.ArrayList;
32+
import java.util.List;
3033

3134
public class ReferenceEnqueue {
3235

3336
public static void main(String args[]) throws Exception {
34-
for (int i=0; i < 5; i++)
37+
for (int i=0; i < 5; i++) {
3538
new WeakRef().run();
39+
new ExplicitEnqueue().run();
40+
}
3641
System.out.println("Test passed.");
3742
}
3843

@@ -76,4 +81,45 @@ void run() throws InterruptedException {
7681
}
7782
}
7883
}
84+
85+
static class ExplicitEnqueue {
86+
final ReferenceQueue<Object> queue = new ReferenceQueue<>();
87+
final List<Reference<Object>> refs = new ArrayList<>();
88+
final int iterations = 1000;
89+
90+
ExplicitEnqueue() {
91+
this.refs.add(new SoftReference<>(new Object(), queue));
92+
this.refs.add(new WeakReference<>(new Object(), queue));
93+
// Can't test PhantomReference because get() always returns null.
94+
}
95+
96+
void run() throws InterruptedException {
97+
for (Reference<Object> ref : refs) {
98+
if (ref.enqueue() == false) {
99+
throw new RuntimeException("Error: enqueue failed");
100+
}
101+
if (ref.get() != null) {
102+
throw new RuntimeException("Error: referent must be cleared");
103+
}
104+
}
105+
106+
System.gc();
107+
for (int i = 0; refs.size() > 0 && i < iterations; i++) {
108+
Reference<Object> ref = (Reference<Object>)queue.poll();
109+
if (ref == null) {
110+
System.gc();
111+
Thread.sleep(100);
112+
continue;
113+
}
114+
115+
if (refs.remove(ref) == false) {
116+
throw new RuntimeException("Error: unknown reference " + ref);
117+
}
118+
}
119+
120+
if (!refs.isEmpty()) {
121+
throw new RuntimeException("Error: not all references are removed");
122+
}
123+
}
124+
}
79125
}

0 commit comments

Comments
 (0)