扩展Thread类的主要优点是什么(或者何时扩展Thread而不是实现runnable)



我想找出扩展Thread类的可能优点是什么?

这是我描述的另一个问题的一部分:在Java中有两种创建线程的方法

    从线程类扩展的
  1. 实现可运行接口
正如这里所解释的,使用可运行接口有几个好处。我的问题是从线程类扩展的优势是什么?我想到的唯一优点是可以从Thread类扩展,我们称它为ThreadExtended类。然后他/她可以在ThreadExtended中添加更多的功能(我不知道那可能是什么),然后当他/她想要创建一个线程时,而不是从thread类扩展,它从ThreadExtended扩展。

使用Thread类而不是Runnable接口有什么优点吗?您知道有哪些类是从Thread类扩展而来的,然后如果用户想要多线程功能,就要求用户从这些类扩展吗?

    public class ThreadExtended extends Thread{
    //override some functions || add more functionality to Thread class
    }
    public class MyThread extends ThreadExtended{
     public void run()
    {
     for(int i=0;i<10;i++)
        {
          System.out.println("Using ThreadExtended instead of Thread directly");
        }
    }
    public static void main(String args[])
    {
    MyThread myThread = new MyThread();
    myThread.start();
    }
    }

很少有令人信服的理由来扩展Thread类。我会想象在大多数情况下,你最终会把所有的'do some stuff'逻辑扔到run方法中。

你绝对应该坚持实现Runnable。通过选择扩展Thread,您正在创建一个可能毫无意义的类层次结构,并且最终会限制您将来重构事物的选择。通过选择实现Runnable,您不需要实现者的血统是什么,并且您可以使用强大的抽象(如ExecutorService)来抽象运行代码块的具体细节。最后,选择实现一个接口而不是扩展一个类是一个很好的实践!

扩展Thread的唯一原因是如果您需要添加与线程本身相关联的行为,而不是线程正在执行的任务。

例如,如果您正在实现一个线程池(没有人应该再这样做了,给定java.util.concurrent),您需要更改线程的行为,以便(1)它可以接受新工作,(2)它将自己返回到线程池。以非常简单的形式:

public void setRunnable(Runnable runnable) {
    this.runnable = runnable;
}
public void run() {
    while (true) {
        // wait on lock
        try {
            this.runnable.run();
        }
        catch (Throwable ex) {
            // do something with exception
        }
        finally {
            // return to pool
        }
    }
}

如果我也配置线程,我发现扩展线程更清楚,例如:

class FileReaper extends Thread {
    FileReaper() {
        setDaemon(true);
        setName(getClass().getSimpleName());
    }
    @Override public void run() {
        // do something
    }
}

简单地说,当您扩展Thread时,它将是您将扩展的唯一类!

扩展Thread还有一个很好的理由——如果你想创建一个loop Thread:

这是一个典型的loop线程实现的例子,使用prepare()和loop()的分离来创建一个初始处理程序来与loop通信。

  class LooperThread extends Thread {
      public Handler mHandler;
      public void run() {
          Looper.prepare();
          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };
          Looper.loop();
      }
  }
UI线程是一个loop thread,但是你可能想要创建你自己的worker loop thread。要了解Looper运行其loop()方法的Thread的行为,请参阅我最近的回答。

最新更新