¿Por qué la Thread
clase se implementó como una clase regular y no como una clase abstracta con un run()
método abstracto?
¿Posiblemente introducirá algún problema? ¿O tiene alguna utilidad en ser así?
Además, Thread.start()
se supone que el método es un método muy específico cuya funcionalidad no puede ser implementada por ninguna otra clase (si no me equivoco). Y, por lo tanto, supongo que la final
palabra clave sería apta para esto más que cualquier otro método.
Pero puedo anular este método y usarlo como quiera,
public class Test extends Thread {
public static void main (String... args) {
Thread test = new Test();
test.start();
}
@Override
public void run() {
System.out.println("New thread started...");
}
@Override
public void start() {
System.out.println("Did anyone tell you I will spawn a new thread??");
}
}
Obviamente solo imprimió,
¿Alguien te dijo que generaré un nuevo hilo?
¿Tiene algún uso anular que no sea confundir al ingeniero que lo reemplaza?
Si no es así, ¿por qué el método no se declaró final en la clase Thread?
java
multithreading
Codebender
fuente
fuente
Thread
clase fuera definitiva. El constructor ya toma un ejecutable, por lo que no se necesita herencia para crear un hilo.Respuestas:
En realidad, esta pregunta se reduce al hecho de que siempre debe preferir la composición a la herencia.
Si la
Thread
clase se declarara comoabstract
, el lenguaje tendría que proporcionar otra clase que se extendiera a partir de ella y que los programadores pudieran usar para crear unThread
. Su pregunta sería entonces acerca de por qué esta claseextends
deThread
no lo esabstract
. Si el lenguaje no proporcionó otra claseextends
desdeThread
, los programadores tendrían que crear su propia clase aextend
partir deThread
y anular elrun()
método.La única explicación posible que puedo dar es que los desarrolladores del lenguaje vieron algunos casos de uso para anular
start
cuando se introdujo la clase en el JDK. La primera versión de Java que utilicé fue 1.5 y personalmente no me he encontrado con un caso de uso en el que haya encontrado la necesidad de anularstart
. Como dijo JB Nizet en su respuestafuente
Por supuesto, puedes optar por dispararte en el pie, pero eso no significa que debas hacerlo.
Porque la forma recomendada de crear un inicio de un hilo es no subclase de hilo. La forma recomendada es definir a
Runnable
y pasarlo como argumento al constructor de Thread:Runnable r = new Runnable() { @Override public void run() { ... } }; Thread t = new Thread(r); t.start();
Si y no. No puede reemplazar la implementación de start () por su propia implementación, pero puede hacer cosas adicionales en start () si lo desea:
@Override public void start() { System.out.println("Did anyone tell you I will spawn a new thread??"); super.start(); }
Dicho esto, si Java se rediseñara desde cero hoy en día, es muy probable que el diseño sea diferente. Recuerde que esta clase data de Java 1.0 y aún es compatible con versiones anteriores.
fuente
¿Estás seguro de que nunca querrás anularlo?
Class MyThreadFactory implements ThreadFactory { @Override public Thread newThread(Runnable r) { return new Thread(r) { @Override public void start() { LOGGER.info("Starting thread " + this); super.start(); } }; } }
fuente
Siento que se deben publicar algunas calirifcaciones para las respuestas:
No ! Yo no lo haría. Es como decir: "¿Estás seguro de que quieres declarar privada esta variable?" Porque si pudiera declarar pública cualquier variable que uso sin temer que otros desarrolladores puedan estropear mi lógica de diseño, la codificación sería muy sencilla. Uno de los propósitos más importantes de los conceptos de OOPS de alcance, abstracción, polimorfismo, manejo de errores, etc. es comunicar a otros desarrolladores el diseño y las intenciones detrás de su código.Como se señaló en la pregunta, cuando anula el método de inicio, nadie lo está forzando para usar super.start (). @Codebender escribió un método de inicio para un hilo sin usar super.start () y el compilador nunca se quejó. Entonces, ¿es libre de romper todo el mecanismo de Threading y se supone que el compilador debe dejarlo pasar? El método de inicio de Thread asegura que el método de ejecución sea llamado y ejecutado en el momento adecuado. Es fundamental para el concepto mismo de Threading. Estaría más que feliz de ser corregido, si me perdiera algo aquí. 2.
Bien, si codebender está permitido por diseño, subclasear Thread y estropear el método de inicio, según esa lógica, es el diseño el que se dispara en el pie. Por otra declaración hecha, (con la que estoy completamente de acuerdo), Runnable es la forma recomendada. Entonces, ¿por qué permitimos que la clase Thread cree una instancia del hilo sin restricciones? A esto le sigue:
Eso en realidad respalda la afirmación de Codebender de que el método de inicio debería ser definitivo cuando dices eso .. ^
El único punto, que es válido, ya se menciona como nota al margen, pero es la respuesta real a esta pregunta.
"Compatibilidad con versiones anteriores".
De hecho, las mejoras se produjeron incluso hasta JDK 5.0, cuando incorporaron muchas adiciones y aclaraciones importantes al modelo de concurrencia de Java. Queremos que la compatibilidad con versiones anteriores sea compatible en todo momento y es por eso que la clase Thread sigue siendo exactamente como era antes, a pesar de que la interfaz Runnable es la forma recomendada hoy en día.
Una vez más, estaría más que feliz de ser corregido, si me perdiera algo.
fuente