Raymond Zheng
Raymond Zheng

Reputation: 119

Does java GC take into account references made in another thread?

Suppose a local variable is defined, then passed into a Thread constructor, where it's saved as a private field of that thread. Then, the thread gets kicked off to run continuously (forever, essentially), while the original method ends.

The local variable reference is gone, but does GC take into account the reference stored by the Thread object?

My scenario is similar to this example snippet:

...

public static void Main(String... args) {
  Foo foo = new Foo()
  MyThread thread = new MyThread(foo)
  ExecutorService executor = Executors.newSingleThreadExecutor();
  executor.execute(thread)
}

...

public class MyThread implements Runnable {

  private Foo foo;

  public MyThread(Foo foo) {
     this.foo = foo;
  }

  public void run() {
     while (true) {
         this.foo.print(); // << throws NullPointerException
         sleep(...)
     }
  }
}

Upvotes: 0

Views: 114

Answers (1)

Talendar
Talendar

Reputation: 2087

Briefly, yes, the GC does take into account the reference stored in MyThread class and won't delete the referenced object. This is due to the fact that Java's garbage collector will only destroy unreachable objects, that is, objects that are not being referenced anywhere in your code (not exactly a general rule, take a look at weak references).

The variable foo is not an actual object, but rather a reference to one. When you pass foo to MyThread's constructor you are not passing the object, but a reference to it. Inside the constructor, you are copyng this reference and storing it inside a member variable of MyThread. Since the run() method of that class will run "forever" (meaning that an instance of MyThread is "alive"), the reference in question will live "forever", thus preventing the referenced object from being garbage collected.

Note that MyThread's name is wrong, so to speak. It doesn't extend Thread and, therefore, it's not a thread. It's simply an implementation of the Runnable interface. A more accurate name would be MyRunnable.

Upvotes: 5

Related Questions