3

I understand that if I create some variable inside the loop in main thread, it will create one, then at next iteration it will create another one with the same name and it will continue till loop is done. No problem, because each iteration the variable which was created is gone, so we can create another one.

But what if I create threads with the same name in the loop. Threads doesn't "terminate" at the same time. So why it's possible? I feel like I should separate JVM work with creating variables and OS work with handling the threads, but want to hear a proper explanation.

for (int i = 0; i < 10; i++) {
    MyFirstThread thread = new MyFirstThread();
    thread.start();
}
  • 1
    The object itself may still exist, but the *variable* that refers to it exited the scope. Scoping is a concept that only makes sense at compile time, not at runtime. – Federico klez Culloca Sep 16 '21 at 12:23
  • 2
    Variable names are there for _your_ convenience. They don't exist at runtime. – Andy Turner Sep 16 '21 at 12:23
  • @Michael I don't think the OP's problem is about scope, I think it's about the difference between variables and referenced objects. So, the linked question might not be helpful. – Ralf Kleberhoff Sep 16 '21 at 12:30
  • @RalfKleberhoff Agree, I thought better of it – Michael Sep 16 '21 at 12:30
  • Note that you could even do this without any variable at all and let the loop body just be `new MyFirstThread().start()` for the exact same effect. – Joachim Sauer Sep 16 '21 at 12:49

2 Answers2

6

You're mixing up objects (class instances) and variables. These are two completely different things in Java.

You can create objects with the new operator, as in new MyFirstThread(). From that point on, they exist "forever", until the garbage collector finds that they are no longer needed, which, for a Thread will not happen before it's finished.

A variable can contain a reference to an object. And as long as an object is referenced by a variable, the garbage collector will not touch it.

Now, in your code

for (int i = 0; i < 10; i++) {
    MyFirstThread thread = new MyFirstThread();
    thread.start();
}

A valid (but simplified) interpretation is that you ten times

  • create a variable named thread,
  • create an object of class MyFirstThread and store a reference to that object in the variable,
  • start that thread,
  • dispose of the variable thread (when execution hits the } end of the iteration = end of scope of the variable).

The key point is that disposing of a variable does not affect the object that it referenced. As long as there's a reason for this object to continue its existence (e.g. the thread still running), it will stay alive and continue to do its job.

While in the loop, e.g. in the second iteration, the first thread variable no longer exists, but the first MyFirstThread instance still exists and runs.

Analogy:

Imagine MyFirstThread instances to be houses, and variables to be sheets of paper where you note the house address.

Then you do ten times:

  • take a fresh sheet of paper,
  • build a house in some location and write down the address on the sheet of paper,
  • using the address from your sheet, order someone to continuously mow the lawn (sorry, not a perfect analogy),
  • throw away the sheet of paper.

In the end, there will be ten houses with perfect lawns, but you will not be able to access them, as you no longer know how to find them.

Ralf Kleberhoff
  • 6,990
  • 1
  • 13
  • 7
  • 2
    In case OP cares,... The reason a `Thread` instance isn't garbage collected while the thread still is running is simple: The `run()` method call is not the bottom of the thread's stack. Some function in the JVM _calls_ `run()`, and _that_ caller has a local variable holding a reference to the `Thread.currentThread()` instance. The caller's local variable continues to exist at least until `run()` either returns or throws an exception. – Solomon Slow Sep 16 '21 at 20:46
  • @SolomonSlow "and that caller has a local variable holding a reference to the Thread.currentThread()", but it's not the same reference which was created before, right? As Ralf mention above, "dispose of the variable thread (when execution hits the } end of the iteration = end of scope of the variable)." Let's say that at first iteration one variable with name "thread" was created, next iteration another one, but first thread isn't complete. That means the first variable now has some different "name" until method is done? Thx! – Ingvar Kokorin Sep 16 '21 at 22:51
  • 2
    @IngvarKokorin There still seems to be some misconception here, so I'll extend my answer a bit. – Ralf Kleberhoff Sep 17 '21 at 08:14
  • 2
    It’s not different to, e.g. `for (int i = 0; i < 10; i++) { Frame f = new Frame(); f.setVisible(true); }`. Some operations, e.g. method `start()` of `Thread` or `setVisible` of `Frame` may cause the object to be referenced by a service provided by the execution environment itself. There are methods, like `Thread.getAllStackTraces().keySet()` or `Frame.getFrames()`, which allow to find those still active objects, even if you don’t have a local reference to them yet. – Holger Sep 17 '21 at 08:59
  • @Holger "may cause the object to be referenced by a service provided by the execution environment itself" I think that what I've tried to find out. Thank you. – Ingvar Kokorin Sep 17 '21 at 11:53
  • 2
    @IngvarKokorin, Read what Ralf added to his answer--the bit about a houses and slips of paper. Re, "It's not the same reference..." That's like saying that the card I gave you with the address of a house is not the same card as the one that I gave to somebody else. OK, the cards aren't the same, but they both refer to the same _house._ In Java, If I my program has `Thread t =...`, and then, `Thread u = t;`, then yeah, `t` and `u` are different variables, but they both refer to the same `Thread` instance. The GC won't reclaim that instance until there are _no_ variables left that refer to it. – Solomon Slow Sep 17 '21 at 12:30
  • 2
    @Holger in my House analogy, using the static `Thread` methods would mean to go to some local authority and ask them about houses owned by me. – Ralf Kleberhoff Sep 17 '21 at 12:37
  • 2
    @RalfKleberhoff or asking them for all land register’s entries and searching the entries for the houses owned by you manually. – Holger Sep 17 '21 at 12:42
0

You just assign reference to the new custom object MyFirstThread to the new variable thread. In the each cycle of the loop variable thread go out of scope and you loose reference to the MyFirstThread and new variable thread created.

Denis Rodin
  • 319
  • 1
  • 7