Skip to content

Commit e633df1

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, dholmes, iris, andrew Backport-of: 330d63d2f9e18ba069e11868d4381059c66f480f
1 parent 5323ef6 commit e633df1

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

+6-1
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

+3-5
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ public void clear() {
265265
this.referent = null;
266266
}
267267

268-
269268
/* -- Queue operations -- */
270269

271270
/**
@@ -282,8 +281,8 @@ public boolean isEnqueued() {
282281
}
283282

284283
/**
285-
* Adds this reference object to the queue with which it is registered,
286-
* if any.
284+
* Clears this reference object and adds it to the queue with which
285+
* it is registered, if any.
287286
*
288287
* <p> This method is invoked only by Java code; when the garbage collector
289288
* enqueues references it does so directly, without invoking this method.
@@ -293,10 +292,10 @@ public boolean isEnqueued() {
293292
* it was not registered with a queue when it was created
294293
*/
295294
public boolean enqueue() {
295+
this.referent = null;
296296
return this.queue.enqueue(this);
297297
}
298298

299-
300299
/* -- Constructors -- */
301300

302301
Reference(T referent) {
@@ -307,5 +306,4 @@ public boolean enqueue() {
307306
this.referent = referent;
308307
this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
309308
}
310-
311309
}

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

+49-3
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)