¿es legal para un hilo llamar a this.start() dentro de su propio constructor? y si es así, ¿qué posibles problemas puede causar esto? Entiendo que el objeto no se habrá inicializado por completo hasta que el constructor se haya ejecutado por completo, pero aparte de esto ¿hay algún otro problema?llamando a thread.start() dentro de su propio constructor
Respuesta
Es legal, pero no acertado. La parte Thread de la instancia se inicializará por completo, pero es posible que su constructor no lo haga. Hay muy pocas razones para extender Thread, y usar trucos como este no ayudará a tu código.
Supongo que quiere hacer esto para que su código sea menos detallado; en lugar de decir
Thread t = new CustomThread();
t.start();
activeThreads.add(t);
puede simplemente decir
activeThreads.add(new CustomThread());
También me gusta tener menos nivel de detalle, pero estoy de acuerdo con el resto de los encuestados que no se debe hacer esto. Específicamente, rompe la convención; cualquiera que esté familiarizado con Java y lea el segundo ejemplo supondrá que el hilo no se ha iniciado. Peor aún, si escriben su propio código de enhebrado que interactúa de alguna manera con el suyo, entonces algunos hilos necesitarán llamar al start
y otros no.
Esto puede no parecer atractivo cuando trabajas solo, pero con el tiempo tendrás que trabajar con otras personas, y es bueno desarrollar buenos hábitos de codificación para que te resulte fácil trabajar con otros y código escrito con las convenciones estándar.
Sin embargo, si no le importan las convenciones y odia la verbosidad adicional, siga adelante; esto no causará ningún problema, incluso si intenta llamar al start
varias veces por error.
Por cierto, si uno quiere verbosidad menor y aún así mantener el constructor con su semántica "estándar", se podría crear un método de fábrica:
activeThreads.add(CustomThread.newStartedThread());
Se es "legal", pero creo el problema más importante es este: Una clase debe hacer una cosa y hacerlo bien.
Si su clase utiliza un subproceso internamente, entonces la existencia de ese subproceso no debería ser visible en la API pública. Esto permite la mejora sin afectar la API pública. Solución: extienda Runnable, no Thread.
Si su clase proporciona una funcionalidad general que, en este caso, sucede ejecutar en un hilo, entonces no desea limitarse a siempre creando un hilo. La misma solución aquí: extender Runnable, no Thread.
Para menos verbosidad En segundo lugar, sugiero usar un método de fábrica (por ejemplo, Foo.createAndRunInThread()).
Por razones de seguridad de la memoria, no debe exponer una referencia a un objeto o los campos de ese objeto a otro subproceso desde su constructor. Suponiendo que su hebra personalizada tenga variables de instancia, al iniciarla desde el constructor, se garantiza que violará las pautas del Modelo de memoria de Java. Ver Brian Goetz's Safe Construction Techniques para más información.
¿Tiene comentarios sobre esta respuesta? No es incorrecto –
¿Votación negativa? Por favor, localice una fuente si cree que esto está mal. Esto es correcto. –
La respuesta no está enlatada en absoluto. A menos que use el constructor Runnable, puede hacer referencia a 'this' desde dentro de 'Thread # run' antes de que el constructor finalice, lo cual infringe las reglas de seguridad de la memoria. Por lo tanto, debes tener cuidado. –
También verá problemas extraños si la clase Thread se subclasifica. En ese caso, terminará con el hilo ejecutándose una vez que el super() salga, y cualquier cosa que la subclase pueda hacer en su constructor podría no ser válida.
@bill barksdale Si el hilo ya se está ejecutando, al llamar de nuevo se obtiene una IllegalThreadStateException, no obtiene 2 hilos.
Legal ... sí (con advertencias como se menciona en otros lugares). Aconsejable ... no.
Solo soy un olor que puedes evitar fácilmente. Si quieres que el hilo se inicie automáticamente, solo hazlo como Heinz Kabutz.
public class ThreadCreationTest {
public static void main(String[] args) throws InterruptedException {
final AtomicInteger threads_created = new AtomicInteger(0);
while (true) {
final CountDownLatch latch = new CountDownLatch(1);
new Thread() {
{ start(); } // <--- Like this ... sweet and simple.
public void run() {
latch.countDown();
synchronized (this) {
System.out.println("threads created: " +
threads_created.incrementAndGet());
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
};
latch.await();
}
}
}
- 1. Inicializando una nueva clase en su propio constructor
- 2. llamando al constructor predeterminado
- 3. La captura de señal dentro de su propio manejador
- 4. Move Constructor llamando a la clase base Move Constructor
- 5. Llamando super constructor en C#
- 6. llamando a la función miembro de Javascript constructor
- 7. Llamando a Clojure desde dentro de R?
- 8. implementar su propio sizeof
- 9. compilando su propio glibc
- 10. Creando su propio idioma
- 11. clase derivada Llamando al método estático de la clase base en su propio método estático
- 12. Llamando al constructor de clase hijo antes del constructor padre
- 13. Spring Bean ejecutándose en su propio hilo
- 14. -su-propio-escribe la consistencia en MongoDB
- 15. ¿Puede una subclase heredar también el constructor de la clase padre, o debe tener cada clase su propio constructor?
- 16. Animación dentro de un embellecedor (llamando OnRender)
- 17. ¿Cómo muevo una rama de Git a su propio repositorio?
- 18. Ventaja de usar Thread.Start vs QueueUserWorkItem
- 19. Creando su propio uid de estilo Tinyurl
- 20. Llamando al constructor padre en PHP
- 21. Escriba su propio administrador de memoria
- 22. Eclipse añadir su propio comando de generación
- 23. ¿Cómo aloja su propio depósito de huevos?
- 24. Trazado columnas llamando a su cabecera con GNUPlot
- 25. llamando a archivos por lotes dentro de nant
- 26. Llamando a la función PHP dentro de Javascript
- 27. Constructor sobrecargado llamando a otro constructor, pero no como primera instrucción
- 28. Llamando predict() dentro de una función R
- 29. escribir mi propio mapa su funcionamiento genérico
- 30. Cómo escribir su propio .net obfuscator
¿cómo es esto relevante para la cuestión del PO? – subsub