run方法完成后的线程类实例

马扬克·库马尔·塔库尔

我正在尝试在 Java 中学习多线程。我们使用两种方法来创建线程,第一种是通过扩展 Thread 类,第二种方法是通过实现 Runnable 接口。

在下面的示例中,我通过实现 Runnable 接口创建了一个线程。


class ThreadExample implements Runnable {

    @Override
    public void run() {
        System.out.println("run method is called by thread named " + Thread.currentThread().getName());

        System.out.println("run method is ending for thread named " + Thread.currentThread().getName());

    }

}

public class TestInterruptingThread2 extends Thread {

    public static void main(String args[]) {
        ThreadExample threadExample = new ThreadExample();
        Thread thread = new Thread(threadExample);
        thread.start();

    }
}

输出是 -

run method is called by thread named Thread-0
run method is ending for thread named Thread-0

如上例所示,要创建 ThreadExample 类的线程,我们首先创建它的对象,然后将其传递给Thread类的构造函数

我的问题是,run()方法完成后,Thread的实例传递给哪个ThreadExample类对象的对象会发生什么它是否有资格进行垃圾收集?

以及如何通过实现 Runnable 接口创建线程比扩展 Thread 类更节省内存?

斯蒂芬·C

它是否有资格进行垃圾收集?

是的。当一个Thread实例终止并且一旦对该对象的所有其他引用都丢失了,它将变得不可访问并且将成为垃圾回收的候选对象。

请注意,线程的堆栈通常会垃圾收集器运行之前被回收(它由线程的终止触发。)


如何通过实现Runnable接口创建线程比扩展Thread更节省内存

这不是真正的问题。

性能涉及对不延长理由Thread的事实,创建和启动A派生Thread或派生类Thread是昂贵的。(在某些平台上,可能需要一毫秒的时间!)因此您希望避免重复创建新Thread对象。

执行此操作的标准方法是使用线程池或ExecutorService. 这些通过将任务封装为 a Runnable(或 a Callable) 并将其传递给长时间运行的工作线程/池线程来工作。这样的线程通常会在其生命周期内处理大量这些任务(一次一个),因此创建线程的成本会在多个任务上分摊……并且变得微不足道。

这与new Thread(Runnable)vs 有extends Thread什么关系

在前一种情况下,您已经将您的任务封装为一个Runnable,因此将您的应用程序转换为使用线程池/执行器相对简单。相比之下,如果您进行扩展,则Thread必须更改明显更多的代码。

现在......您可以为您的自定义线程类实现一个线程池。然而,典型的线程池实现有一些复杂的逻辑和线程安全问题,所以这是一个坏主意。


扩展Thread也是一个坏主意还有其他原因但是您只是询问与性能相关的原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章