Сценарий, в котором расширение потока предпочтительнее, чем реализация Runnable?

Как новичок, я читал о двух способах реализации многопоточности в Java.

Я прочитал этот поток в SO и во многих других потоках.

Утверждается, что

"предпочитает runnable", расширяет поток только тогда, когда вы специализируетесь на поведении.

Может кто-нибудь объяснить мне, что имеется в виду, специализируясь на поведении Thread, предоставив мне небольшой фрагмент фрагмента, который поможет мне понять эту строку.

Ответ 1

Вы должны расширить Thread столько, сколько вы расширяете другие классы библиотек.

Возьмите List, например, более конкретно ArrayList, вы можете добавить к нему дополнительное поведение, например, отклонить значение при добавлении, если сбой определенного предиката.
Тогда вы можете назвать это PredicatedArrayList.

По-прежнему обсуждается вопрос о том, хотите ли вы расширить ArrayList здесь или нет, но эта дискуссия не подходит для этого вопроса.

Таким образом, пример продолжения потока будет потоком, который убивает себя через определенное количество времени. Тогда у вас будет SuicidingThread extends Thread, который может иметь конструктор, требующий времени.

Это даже усиливает аргумент о том, что вы должны поставить свои фактические задачи в Runnable.
Как Runnable somethingRunnable = new SomeClass();, где SomeClass implements Runnable.

Теперь вы можете сделать:

  • Thread someThread = new Thread(somethingRunnable);
  • Thread someThread = new SuicidingThread(somethingRunnable, 5, TimeUnit.DAYS);

Таким образом, это будет проблемой для расширения потока.

Ответ 2

Специализирующие средства расширяют функциональность существующего класса Thread. Это может быть все, что зависит от требования приложения. То, что я упомянул ниже, может быть неверным логически.

public class MyThread extends Thread{
@Override
public void interrupt() {
    if(thread has started some operation on database){
        //roll back transaction
    }
    super.interrupt();
}
}

Здесь, прежде чем прерывать поток, мы можем проверить, запущена ли какая-либо операция базы данных в настоящий момент и откат ее. Хотя это можно сделать из прерванного блока catch, обработка его из расширенного класса уменьшает количество строк, если вы создаете множество экземпляров этого потока в разных местах приложения. Это просто пример, никто не будет использовать его таким образом.:)

Ответ 3

Потому что java не поддерживает многоуровневое. Если у вас есть класс с именем Person.

class Person{
 String name;
 int age;
}

Затем вы хотите создать класс Man, который расширяет Person

class Man extends Person{

}

Теперь вы использовали ключевое слово extends, чтобы объявить, что Man является Person. Затем, если вы хотите, чтобы Man выполнялся как поток, вы не можете повторно расширять Thread, потому что Java не поддерживает многоуровневое. Просто используйте интерфейс Runnable, который может быть реализован вместе с другими интерфейсами.

class Man extends Person implements Runnable{
  public void run()[
  }
}

EDIT: "extends thread only when you special special Thread" означает, что ваш класс - это только Thread, у которого нет других функций, потому что, когда ваш класс содержит другие функции, вам нужно расширить класс суперкласса, а не класс Thread. Как Я уже упоминал, что java не поддерживает многоуровневое наследование, поэтому просто расширяет поток только тогда, когда вы специализируетесь на поведении Thread.

Ответ 4

Java не поддерживает множественное наследование, а это значит, что вы можете продлить один класс только на Java, поэтому, как только вы расширили класс Thread, вы потеряли свой шанс и не можете расширять или наследовать другой класс в Java, поэтому этот класс специализирован для Thread только.

В extending Thread каждый из ваших потоков имеет уникальный объект, связанный с ним, тогда как при реализации Runnable многие потоки могут совместно использовать один и тот же исполняемый экземпляр.

Расширение класса обычно означает добавление новых функций, изменение или улучшение поведения. Если мы не внесем каких-либо изменений в Thread, используйте вместо этого Runnable.

Класс Thread имеет определенное поведение разработчиков JDK, если вы хотите внести в него некоторые изменения, тогда вы можете расширить свой класс с помощью класса Thread и изменить его.

Ответ 5

Существует несколько причин, чтобы предпочесть реализацию Runnable по расширению Thread:

  • Всегда предпочитайте композицию над наследованием, и в итоге вы получите менее связанный код. Один из способов решить, как ваш класс связан с Thread, - это проверить отношение "is a" и "has a".

  • На практике расширение Thread заставит вас создавать экземпляры новых экземпляров вашего класса для каждого потока, вместо того, чтобы использовать один и тот же экземпляр в случае Runnable. См. это.

  • Java поддерживает только одно наследование

Одним из примеров законных вариантов использования продолжения Thread является необходимость создания класса Thread с пользовательскими свойствами (например, кэширование ресурсов), который является частью CachedThreadPool