2013-05-10 2 views
6

Я пытаюсь выяснить, каковы возможные преимущества расширения класса Thread?В чем основное преимущество расширения класса Thread (или при расширении Thread вместо реализации runnable)

Это является частью другого вопроса, который я описываю: Существует два способа создания потоков в Java

  1. простирающихся от класса Thread
  2. реализации работоспособного интерфейса

Как 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(); 
    } 
    } 
+1

Существует только один способ создания потока в java, и это значит создать экземпляр 'Thread' и вызвать' start() 'на нем. –

+0

@SotiriosDelimanolis Я понимаю, что я спрашиваю о продлении, а не создании экземпляра – sheidaei

+0

Пожалуйста, обратите внимание на вопрос, который я задал, он немного отличается от того, который, по вашему мнению, является дубликатом. Спасибо – sheidaei

ответ

7

Существует редко веская причина для расширения класса Thread. Я бы предположил, что в большинстве случаев вы в конечном итоге просто выбросите всю свою логику «сделайте что-нибудь» в метод run.

Вы должны обязательно придерживаться внедрения Runnable. Выбрав расширение Thread, вы создаете иерархию классов, которая, вероятно, бессмысленна и приведет к ограничению ваших возможностей для рефакторинга вещей в будущем. Выбирая для реализации Runnable, вы не предъявляете никаких требований к тому, что является родословной исполнителя, и вы можете использовать мощные абстракции, такие как ExecutorService, чтобы отвлечь гайки и болты от запуска куска кода. Наконец, предпочтительная реализация интерфейса, а не расширение класса - хорошая практика!

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 
     } 
    } 
} 
1

Я нахожу это более ясным, чтобы расширить тему, если я также настроить нить, например:

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

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

Проще говоря, когда вы расширяете тему, что будет единственным классом вы будете расширяться!

0

Существует также хороший повод расширить Thread - если вы хотите создать петлитель:

Это типичный пример реализации нити Looper, используя разделение подготовки() и цикл(), чтобы создать начальный обработчик для связи с Looper.

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(); 
     } 
    } 

Нити потока - это Looper Thread, но вы можете создать свою собственную Looper Thread. Чтобы узнать, как работает Thread с Looper, на котором работает его метод loop(), см. Мой недавний ответ here.

Смежные вопросы