0

run()方法在新线程中运行时,它将有自己的堆栈。countdown不同堆栈中的 run 方法如何访问来自主线程的变量(如本例中的变量)?

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();
4

3 回答 3

3

虽然每个线程都有自己的堆栈,但它与程序的其余部分共享同一个堆。普通类和变量范围适用于这种情况,因为该run()方法位于外部类的匿名内部类中,因此它可以访问其宿主类的成员。

countdown变量没有被压入堆栈。如果它作为参数传递给方法,那么它将被压入堆栈。

于 2013-09-25T14:13:51.353 回答
3

堆栈上的变量是线程本地的。CPU 在本机级别支持堆栈和线程,而不是 Java 的细节。

但是,在您的示例中,countdown它被复制到您创建的 Thread 子类上的字段中,因此它是对象的字段,而不是堆栈局部变量。(事实上​​你似乎没有)

在字节码中,它可能会使用堆栈,但一旦优化,它很可能根本不会使用堆栈。而是使用寄存器。

于 2013-09-25T14:15:34.457 回答
1

匿名内部对象被赋予对幕后封闭类的引用。

有关该主题的出色Jon Skeet答案,请参见此处。

于 2013-09-25T14:11:04.183 回答