From: ###@###.### (Rich Cohen)
This does not look like form output to me.
There appears to be a bug in the Ref class as defined in JDK 1.0.
There is a potential race condition in the definition of Ref.get.
Ref.get could return a null pointer if the object gets flushed in
another thread. (The documentation is unclear, but it appears that
Ref.get is not intended to return null pointers, since a null pointer
triggers a call to reconstitute.)
This problem can be avoided simply by returning the value of a local
variable, rather than returning the value of a shared variable.
I've appended the erroneous source code and an appropriate fix.
-- Rich Cohen
From JDK 1.0 file Ref.java:
/*
* @(#)Ref.java 1.17 95/09/06
*
*/
[...]
/**
* Returns a pointer to the object referenced by this Ref. If the object
* has been thrown away by the garbage collector, it will be
* reconstituted. This method does everything necessary to ensure that the garbage
* collector throws things away in Least Recently Used(LRU) order. Applications should
* never override this method. The get() method effectively caches calls to
* reconstitute().
*/
public Object get() {
Object p = thing;
if (p == null) {
/* synchronize if thing is null, but then check again
in case somebody else beat us to it */
synchronized (this) {
if (thing == null) {
p = reconstitute();
thing = p;
}
}
}
priority = ++lruclock;
/* *** Erroneous code from JDK: ***
return thing; */
/* *** Better code: ***/
return p;
}
This does not look like form output to me.
There appears to be a bug in the Ref class as defined in JDK 1.0.
There is a potential race condition in the definition of Ref.get.
Ref.get could return a null pointer if the object gets flushed in
another thread. (The documentation is unclear, but it appears that
Ref.get is not intended to return null pointers, since a null pointer
triggers a call to reconstitute.)
This problem can be avoided simply by returning the value of a local
variable, rather than returning the value of a shared variable.
I've appended the erroneous source code and an appropriate fix.
-- Rich Cohen
From JDK 1.0 file Ref.java:
/*
* @(#)Ref.java 1.17 95/09/06
*
*/
[...]
/**
* Returns a pointer to the object referenced by this Ref. If the object
* has been thrown away by the garbage collector, it will be
* reconstituted. This method does everything necessary to ensure that the garbage
* collector throws things away in Least Recently Used(LRU) order. Applications should
* never override this method. The get() method effectively caches calls to
* reconstitute().
*/
public Object get() {
Object p = thing;
if (p == null) {
/* synchronize if thing is null, but then check again
in case somebody else beat us to it */
synchronized (this) {
if (thing == null) {
p = reconstitute();
thing = p;
}
}
}
priority = ++lruclock;
/* *** Erroneous code from JDK: ***
return thing; */
/* *** Better code: ***/
return p;
}