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

时间:2013-05-10 18:55:26

标签: java multithreading

我试图找出扩展Thread类的可能优势是什么?

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

  1. 从Thread类
  2. 扩展
  3. 实施runnable接口
  4. 作为expalined here,使用runnable接口有几个好处。我的问题是从Thread类扩展的优势是什么?我想到的唯一优势是可以从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();
        }
        }
    

5 个答案:

答案 0 :(得分:8)

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

你绝对应该坚持实现Runnable。通过选择扩展Thread,您创建的类层次结构可能是荒谬的,并且最终会限制您在将来重构事物的选项。通过选择实现Runnable,你不需要实现者的血统,你可以使用像ExecutorService这样强大的抽象来抽象出运行一大块代码的细节。最后,更喜欢实现一个接口而不是扩展一个类是一个好习惯!

答案 1 :(得分:5)

扩展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
        }
    }
}

答案 2 :(得分:1)

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

class FileReaper extends Thread {
    FileReaper() {
        setDaemon(true);
        setName(getClass().getSimpleName());
    }

    @Override public void run() {
        // do something
    }
}

答案 3 :(得分:0)

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

答案 4 :(得分:0)

如果你想创建一个Looper线程,还有一个很好的理由来扩展Thread

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

  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线程是一个Looper线程,但您可能想要创建自己的工作者Looper线程。要了解Thread Looper如何运行loop()方法,请参阅我最近的回答here