【问题标题】:Thread initialized to null in javajava中的线程初始化为null
【发布时间】:2012-05-26 04:24:19
【问题描述】:
public class ThreadState {

    public static void main(String[] args){
            Thread t = new Thread(){
            public void run(){
                       // infinite loop
                       while (true) {
                        try {

                         Thread.sleep(1000);
                        }
                        catch (InterruptedException e) {
                        }

                        System.out.println("thread is running..."+Thread.currentThread().toString());
                       }

            }
        };
        t.start() ; 
        t = null ;
        while (true) {
              try {

              Thread.sleep(3000);
              }
              catch (InterruptedException e) {
              }
              System.out.println("thread is running..."+Thread.currentThread().toString());
        }   

    }
}

线程实例 t 被初始化为 null .. 它仍然能够运行并在控制台上打印其详细信息。需要解释一下

【问题讨论】:

  • 这行t = null;会不会有什么关系?
  • 您在启动后将其设置为 null。有什么问题?
  • 我认为 t = null 应该会影响线程执行。由于线程没有引用,它应该给出一些例外..这就是我的怀疑所在。如果你认为我错了,你可以让我理解

标签: java multithreading


【解决方案1】:

线程实例t被初始化为null

否,Thread 变量 设置为空值。变量不是实例——值得绝对确保你理解这一点。

更改变量的值根本不会影响现有的Thread 对象。

【讨论】:

    【解决方案2】:

    t = null; 只是删除对Thread 实例的引用。
    它不会影响线程本身。

    特别是,执行中的 Thread 实例永远不会被 GC。

    【讨论】:

      【解决方案3】:

      @JonSkeet 和其他人已经很好地解释了,然后你设置t = null 你根本没有改变正在运行的Thread,你只是改变了变量t。一旦线程启动,JVM 就会管理线程,因此即使没有对它的引用,它仍然会运行并且不会被 GC。

      要指出的另一件事是,在接下来的循环中,您正在执行以下操作:

      System.out.println("thread is running..."+Thread.currentThread().toString());
      

      不是打印出您刚刚分叉的线程的状态,而是打印出当前线程——进行分叉的线程。这是运行main() 方法的“主线程”。主线程可以完成,并且您分叉的线程将继续运行——阻止 JVM 退出。只有当你派生的线程被标记为守护线程时,JVM才会在主线程完成时完成。

      【讨论】:

        【解决方案4】:

        您将 t 设置为 null,这对线程本身没有任何作用,它只是将 null 分配给您存储对实例的引用的变量。

        也许这会有所帮助:

        如果你这样做了会怎样

        Object t = new Thread() {...}
        t.start
        Thread t2= (Thread)t;
        t="Orange";
        

        你会期待神奇的事情发生吗?如果您将 t 传递给另一个方法而不是在 t2 中存储另一个引用会怎样?

        t 只是对线程的引用的占位符,给 t 赋值对线程的影响与给下面的 a 赋值 null 对数字 2 的影响一样大。

        Integer a = 2;
        a=null;
        

        【讨论】:

          【解决方案5】:

          我认为 Jon 是正确的,即“更改变量的值根本不会影响现有的 Thread 对象。”

          但你需要的实际解释是

          在使用线程本地的静态或全局内存的编程方法中。 因为通常一个进程中的所有线程共享相同的地址空间,这有时是不可取的。 换句话说,当来自同一进程的线程引用时,静态或全局变量中的数据通常总是位于相同的内存位置。每个线程都有自己的堆栈。

          希望给出的概念性解释有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-06-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多