代码之家  ›  专栏  ›  技术社区  ›  Bhaskar

Java-在线程上调用启动方法:它如何路由到可运行接口的运行()?

  •  6
  • Bhaskar  · 技术社区  · 16 年前

    好的,我知道创建一个新线程并用Java运行它的两种标准方法:

    1. 实施 Runnable 在类中,定义 run() 方法,并将类的实例传递给新的 Thread . 当 start() 方法,则调用类实例的run方法。

    2. 让类派生自 螺纹 ,所以它可以重写方法 () 当一个新实例 START() 方法,调用被路由到重写的方法。

    在这两种方法中,基本上 螺纹 对象被创建并调用其start方法。然而,在第二个方法中,调用被路由到用户定义的 () 方法非常清楚(这是play中的一个简单的运行时多态性),我不理解如何调用 START() 线程对象上的方法被路由到 () 类实现的方法 可运行的 接口。做 螺纹 类具有类型为的私有字段 可运行的 它首先检查哪个,如果已设置,则在设置为对象时调用run方法?我认为这是一个奇怪的机制。

    电话怎么打 START() 在线程上被路由到 可运行的 在构造线程时对象作为参数传递的类实现的接口?

    5 回复  |  直到 12 年前
        1
  •  7
  •   Gray droiddeveloper    12 年前

    这个 Thread 保持对 Runnable 实例,并在 run .

    您可以在源代码中看到这一点:

    // passed into the constructor and set in the init() method
    private Runnable target;
    ...
    // called from native thread code after start() is called
    public void run() {
        if (target != null) {
            target.run();
        }
    }
    
        2
  •  2
  •   nos    16 年前

    虽然您可以查看实际的源代码,但可以猜测它可能是:

    public class MyThread implements Runnable {
     private  Runnable r;
     public MyThread() {
     }
     public MyThread(Runnable r) {
            this.r = r;
     }
    
     public void start() {
       //magic to launch a new thread
       run(); // the above magic would probably call run(), rather than
              // call it directly here though.
      }
      public void run() {
        if(r != null) 
           r.run();
       }
    }
    

    简而言之,如果扩展mythread并重写run(),将调用run()方法。如果您传递的是runnable,mythread的run()方法将只委托给该runnable的run()方法。

        3
  •  1
  •   bragboy    16 年前

    在这两种情况下都必须有具体的线程类。在第一种情况下(实现runnable),使实现它的类能够成为线程。您仍然必须将类作为参数传递给线程类的构造函数。然而,这不是第二种情况下扩展线程类的情况。

    调用start()方法时,不能保证立即调用run()方法。调用start()方法表示线程已准备好运行。之后,它可以根据线程池器转到任何状态。

    FY: class Thread implements Runnable

        4
  •  1
  •   Pyrolistical    16 年前

    你可以查一下 Thread.java 作为JDK的一部分包括:

    public void run() {
        if (target != null) {
            target.run();
        }
    }
    

    目标是:

    private Runnable target;
    

    但我认为你真正想要的答案是线程如何工作的细节。不幸的是,这在本机库中被抽象出来了。试着对线程的工作原理有一个更高层次的理解。

        5
  •  1
  •   Donal Fellows    16 年前

    有一件事还没有被答案探究,那就是事情是如何从 start() run() ,既简单又复杂。

    简单来说, START() 方法调用本机方法( start0 在OpenJDK实现中,它为一个新的堆栈分配一些内存,并要求OS运行一个线程,这个空间是堆栈和一个简单的C++函数。 thread_entry 在openjdk实现中)作为实现函数。该函数又将think返回到Java调用 () 线程对象上的方法。任何在posix系统或windows中执行本机线程的人都应该熟悉底层的模式(要求os在堆栈上启动一个新线程并使用一个函数)。

    这个细节让事情变得更加复杂,错误处理和模糊的边缘情况都需要处理。如果你好奇,请阅读 OpenJDK 来源,特别注意 Thread.java , JVM_StartThread 在里面 jvm.cpp 以及 JavaThread 班在 thread.cpp thread.hpp . 希望这个答案能给你足够的细节,让你找到自己的路…