Assume this code:
public class Foo {
public static Thread thread;
public String thing = "Thing!!";
public static void main(String[] args) {
new Foo().makeThread();
// <- Foo object may get garbage collected here.
thread.start();
}
private void makeThread() {
thread = new Thread(new Runnable() {
@Override
public void run() {
// !! What if the instance of Foo is long gone?
System.out.println(thing);
}
});
}
}
Here, a temporary object new Foo()
creates a statically held Thread thread
which utilizes an instance-tied String thing
in an anonymous implementation of Runnable
. Does the String thing
get garbage collected after expiration of new Foo()
, or will it persist for its use within run()
? Why?
The anonymous inner class will have a reference to the Foo
, as that's how it is about to access thing
. It's as if you had:
public class FooRunnable implements Runnable {
private final Foo foo;
public FooRunnable(Foo foo) {
this.foo = foo;
}
public void run() {
System.out.println(foo.thing);
}
}
Then:
private void makeThread() {
thread = new Thread(new FooRunnable(this));
}
So basically, while the new thread keeps an instance of the Runnable
implementation alive, that in turn prevents the instance of Foo
from being garbage collected.
See more on this question at Stackoverflow