Почему класс java.lang.Thread в Java не помечен окончательно разработчиками? - PullRequest
6 голосов
/ 27 марта 2011

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

Ответы [ 6 ]

3 голосов
/ 27 марта 2011

С исторической точки зрения вы должны понимать, что API Thread был разработан в Java 1.0, прежде чем Java поддерживала анонимные внутренние классы.И большая часть кода в раннем примере показывает подклассы Thread.Только позже:

  • они добавили поддержку анонимных внутренних классов (Java 1.1)
  • они поняли, что лучше использовать внутренние классы (и т. Д.) Для обеспечения Runnable экземпляров
  • они реализовали стандартные классы для выполнения задач, пулов потоков и т. Д. (Java 5.0).

Все очень хорошо говорят "класс Thread в.Net помечен как окончательный ", но вы должны понимать, что C # / .Net появился несколько лет спустя ... и смог извлечь уроки из дизайна Java.Java была / застряла с историческим багажом ряда неидеальных дизайнерских решений ... из-за непреодолимой необходимости НЕ ломать старый код.

3 голосов
/ 27 марта 2011

достичь той же функциональности реализации Runnable и передать его Поток конструктор

Использование расширения Thread не ограничено Runnable. Например, вы можете изменить поведение некоторых методов или добавить собственную локальную информацию потока (всегда доступную с Thread.currentThread()).

2 голосов
/ 27 марта 2011

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

Я думаю, что нет веской причины либо отмечать Thread final и требовать внешнего Runnable, либо делать Thread расширяемым и иметь собственный Runnable. Оба подхода прекрасно подходят, и ни один из них не выглядит намного лучшим выбором, чем другой.

Если бы мне пришлось угадывать, причина создания подкласса Thread заключается в том, что он позволяет писать код, подобный этому:

Thread t = new Thread() {
    public void run() {
       /* ... your code here ... */
    }
};

Что немного чище, чем создание подкласса Runnable, а затем завернуть его в поток. Точно так же вы можете подкласс от Thread, чтобы получить Runnable, который ясно указывает, что он должен использоваться в качестве потока. Конечно, это в основном вопрос эстетики, и если бы Java-дизайнеры пошли другим путем, я думаю, это было бы идеальным решением.

0 голосов
/ 21 марта 2012

Единственное, о чем я могу подумать: если вы расширяете класс Thread, он позволяет вашему методу run () быть отмеченным как защищенный.Один недостаток реализации Runnable заключается в том, что ваш метод запуска ДОЛЖЕН быть помечен как открытый.

0 голосов
/ 27 марта 2011

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

0 голосов
/ 27 марта 2011

Если я могу добавить что-то, расширяя Thread, вы можете иметь расширенную функциональность потока (которого нет в Runnable, так как он содержит только метод run()), например, позволяя вашему потоку действовать как поток демона (точно так же как поток демона Сборщика мусора).Существуют и другие потоки, такие как единственный поток, не являющийся демоном, который вызывает метод main класса (при запуске JVM).

Интерфейс Runnable позволяет вашему классу стать активнымпоток (путем реализации метода run()).

...