【问题标题】:start() method called for a thread from a start() ... confusing从 start() 调用线程的 start() 方法...令人困惑
【发布时间】:2018-02-15 18:55:09
【问题描述】:

我一直在努力创建一个运行渲染的线程,我遇到了这种实现方式:

Class Main implements Runnable {
private Thread thread;
private boolean running = false;

public void start() {
            running = true;
    thread = new Thread(this, "renderingThread")
    thread.start(); //calls run()
}

    public void run() {

    init(); //init glfw + create window

    while(running) {
        update();
        render();
    }
}

    public static void main(String[] args) {
        new Main().start()
    }

请注意,仅包含与线程相关的代码部分。

现在,程序流程看起来像这样(如果我错了,请纠正我):构造类型/类 Main 的新对象(因此,在堆上保留一个位置)。然后,调用 Main 类型对象的 start() 方法。 running 布尔值设置为真。然后,通过构造函数Thread(Runnable target, String name)创建一个新线程——在我的例子中,第一个参数是this关键字,意思是对象的引用Main 类型的第一个参数被传递(因为该方法已被 Main 类型的对象调用)。然后,下一行是最让我烦恼的。 thread 引用调用方法 start(),但它以某种方式引用了 run() 方法。怎么样?

非常感谢您详细解释线程对象的 start() 方法如何引用 run() 方法。

【问题讨论】:

  • 这是你 - 大概 - 写的代码。 start() 方法的存在完全是您的选择,与线程本身使用也称为start() 的方法启动这一事实无关。

标签: java multithreading lwjgl


【解决方案1】:

您创建一个新的Thread,其Runnable 目标为thisMain 类的实例)。 Main implements Runnable 表示方法 run() 被覆盖。 Thread 类本身实现了Runnable

当你用上面的配置启动线程时,方法start()会导致线程开始执行; Java 虚拟机然后调用Thread 对象的run() 方法。在documentation 中说。好奇的可以看java.lang.Thread的源码。

你可以用更简单的方法达到同样的效果:

public class Main implements Runnable { 

    @Override
    public void run() {
        System.out.println("New thread");
    }

    public static void main(String[] args) {
        new Thread(new Main()).start();
        System.out.println("Main thread");
    }
}

【讨论】:

  • start() 间接调用run() 可能会产生误导。有人可能会想到start() 调用的东西调用了......调用run() 的东西。但事实并非如此。对run() 的调用发生在与start() 调用不同的线程中。
  • @jameslarge 不。请参阅我的答案中链接的源代码。当您调用调用私有本机 void start0() 的 start() 方法时,会创建一个新线程,然后在这个新线程中执行 run() 方法 - 这是间接的。
  • @NikolasCharalambidis,通常,当有人说“A 间接调用 B”时,他们谈论的是在单个线程中发生的事情。如果你说start()间接调用run(),那么懂线程的人就懂你的意思,而菜鸟不懂。菜鸟无法知道您正在以不寻常的方式使用“间接调用”这个短语。有很多菜鸟编写多线程代码,但对线程是什么没有任何实质性的了解,这就是这些答案应该针对的对象。
  • @jameslarge 我认为自己是多线程领域的菜鸟。此外,将任何人称为菜鸟是不公平的,因为每个人都是一个人。没错,我可能对我的答案的理解与 OP 不同,因为 Java 知识各不相同,而且主要是我不是以英语为母语的人,所以我没有这样的权利...... 单词的味道(如果我可以这样说的话)。因此,感谢您的反馈,我编辑我的答案。 :))
  • 我在很多事情上都是菜鸟。我不知道这是一个令人反感的词。我应该猜到了。如果还有什么话还没有冒犯性的话,它们可能不会持续太久。
【解决方案2】:

看看 JavaDoc (https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#start--)

当在 Thread 对象上调用 start() 时,它会创建一个新线程并在该线程上调用 run() 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多