【问题标题】:Java - implementing Runnable acts different compared to extending ThreadJava - 与扩展 Thread 相比,实现 Runnable 的行为不同
【发布时间】:2016-11-09 07:49:55
【问题描述】:

我正在尝试了解多线程的工作原理。这是我的示例代码:

public class Processor extends Thread {
    private boolean running = true;

    public void run() {
        while (running) {
            System.out.println("Hello there!");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void shutDown() {
        running = false;
    }

}

public class ProcessorDemo {
    public static void main(String[] args) {

        Processor proc1 = new Processor();
        proc1.start();

        System.out.println("Press return to stop");
        Scanner sc = new Scanner(System.in);
        sc.nextLine();
        proc1.shutDown();

    }

}

当我实现 Runnable 而不是扩展 Thread 时,就会出现问题 - 代码差异

public class Processor implements Runnable

// in ProcessorDemo
Thread proc1 = new Thread(new Processor());

发生的情况是,代码给出了一个错误,说: “线程类型的方法shutDown() 未定义”

为什么会发生这种情况,两种创建线程的方式都应该给出相同的结果?

谢谢大家:)

【问题讨论】:

  • 这是一个高度特定于环境/语言的问题。请在您的问题中包含该信息。最好在标签中。
  • “创建线程的两种方式应该给出相同的结果”——这是不正确的。为什么你认为这是真的?
  • 您的意思是说您的第二个版本根本无法编译吗?这并不完全是“行为不同”,因为你根本没有运行它。

标签: java multithreading runnable


【解决方案1】:

您的代码无法编译,因为 java.lang.Thread 类没有定义 shutDown() 方法;这是您在 Processor 类中定义的方法。

仔细查看java.lang.Threadhttps://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html 上的哪些方法可用。如果您想停止一个线程,我建议您根据您的特定需求查看.interrupt().join()

如何使用.interrupt()的示例:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Thread proc1 = new Thread(new Processor());
        proc1.start();

        System.out.println("Press return to stop");
        Scanner sc = new Scanner(System.in);
        sc.nextLine();
        proc1.interrupt();

    }
}

class Processor implements Runnable {
    public void run() {
        while (! Thread.interrupted()) {
            System.out.println("Hello there!");
        }
    }
}

我通常自己实现Runnable 接口,而不是继承Thread,但您必须考虑哪个更适合您的用例。

【讨论】:

    【解决方案2】:

    在第一种情况下,您使用类型“处理器”初始化了您的引用。因为,类处理器有方法'shutDown()'。 JVM 可以在类处理器中找到该方法。 处理器 proc1 = new Processor();

    在第二种情况下,“处理器实现可运行”。您使用类型“线程”初始化了对象“proc1”。 Wheares 类型 'Thread' 没有方法 'Shutdown'。只有你的类“处理器”有方法“关闭()”

    这就是为什么在尝试调用 'proc1.shutDown()' 时会收到错误为 'method undefined' --> 这实际上意味着方法 'shutDown()' 在类 'Thread' 中不可用

    Processor proc1 = new Processor();
    Thread proc1 = new Thread(proc1);
    proc1.shutDown();
    

    【讨论】:

    • 那么我在实现时如何使用它呢?
    • 在答案中添加了代码。在您的主要方法中替换该设置。它会工作
    【解决方案3】:

    第二个例子中的问题: 请记住,您正在使用 Thread 实例来调用实际存在于您的 Processor 类中的方法 shutDown()

    但在您的第一个示例中并非如此。您使用Processor 实例调用shutDown() 是合法的。

    【讨论】:

      【解决方案4】:

      在第一个示例中,类Processor 被定义为具有一个方法shutdown。因此在实例化Processor时,该方法存在。

      在第二个示例中,shutdown 存在于类 Processor 下,而您尝试在类 Thread 上调用它。

      在本例中,类 Thread 从未扩展,因此没有任何附加功能,如第一个示例中的扩展类 Thread (Processor)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-16
        • 1970-01-01
        • 2012-02-15
        • 1970-01-01
        • 2014-06-02
        • 2013-08-20
        • 2015-04-01
        • 1970-01-01
        相关资源
        最近更新 更多