0

When run() method runs in new thread, it will have its own stack. How are the variables (like countdown in this case) from the main thread accessed by the run method in different stack?

final CountDownLatch countdown = new CountDownLatch(1);
for (int i = 0; i < 10; ++ i) {
   Thread racecar = new Thread() {    
      public void run()    {
         countdown.await(); //all threads waiting
         System.out.println("Vroom!");
      }
   };
   racecar.start();
}
System.out.println("Go");
countdown.countDown();
Gray
  • 115,027
  • 24
  • 293
  • 354
beinghuman
  • 2,088
  • 7
  • 27
  • 36

3 Answers3

3

While each thread has its own stack, it shares the same heap with the rest of the program. The normal class and variable scoping applies in that case since the run() method is in an anonymous inner class of the outer class, so it has access to the members of its host class.

The countdown variable is not being pushed on the stack. If it was being passed as a parameter to the method then it would be pushed on the stack.

jbx
  • 21,365
  • 18
  • 90
  • 144
  • You mean every new Thread will have reference to countdown variable which is stored in the heap?How it is being passed as a parameter? – beinghuman Sep 25 '13 at 14:20
  • Thats the point it is not being passed as a parameter, so it is not on the stack. The stack just keeps a record of which method calls are being called and the parameters being passed, so that they are 'popped off' in reverse order. On the other hand, when a new anonymous class is instantiated it is provided (behind the scenes) with the extra context information it is operating in, such as the member variables of the object hosting the anonymous class instance. – jbx Sep 25 '13 at 14:22
  • Not really. The reference to the `countdown` object is certainly stored on the stack (or a register) although that's an implementation detail. What happens is that the inner class gets the address `countdown` points to passed behind the scenes. This implementation is also the reason why the variable has to be final - a later assignment to countdown wouldn't have any effect after class creation. Real closures would indeed create some kind of wrapper on the heap, but alas we don't have those in java. – Voo Sep 25 '13 at 14:35
3

Variables on the stack are local to the thread. The stack and thread is support at the native level by the CPU and not a detail of Java.

However, in your example, countdown is copied to a field on the sub-class of Thread you created, so it is a field of the object, not a stack local variable. (In fact you don't appear to have any)

In byte code, it may use the stack, but once optimised, most likely it won't use the stack at all. Instead registers are used.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Could not get this statement "In byte code, it may use the stack, but once optimised, most likely it won't use the stack at all. Instead registers are used" – beinghuman Sep 25 '13 at 14:22
  • @Niks real computers have registers, these registers are not only much faster than accessing the stack, many operations only work using registers. For this reason use of the stack can be optimised away in simple methods calls. – Peter Lawrey Sep 25 '13 at 14:28
1

The anonymous inner object is given a reference to the enclosing class behind the scenes.

See here for an excellent Jon Skeet answer on the subject.

Community
  • 1
  • 1
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213