tutorialspoint threads thread que multithread multi manage implement example java multithreading

java - threads - llamando a thread.start() dentro de su propio constructor



runnable java (7)

Es "legal", pero creo que el problema más importante es este: una clase debería hacer una cosa y hacerlo bien.

Si su clase usa un hilo internamente, entonces la existencia de ese hilo 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, se ejecuta en un hilo, no quiere limitarse a crear siempre un hilo. La misma solución aquí: extender Runnable, no Thread.

Para menos verbosidad, secundo la sugerencia de utilizar un método de fábrica (por ejemplo, Foo.createAndRunInThread ()).

Esta pregunta ya tiene una respuesta aquí:

¿Es legal que un hilo llame 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?


Es legal, pero no sabio. 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.


Legal ... sí (con advertencias como se menciona en otro lugar). Aconsejable ... no.

Solo soy un olor que puedes evitar fácilmente. Si quieres que tu hilo se inicie automáticamente, 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(); } } }


Por cierto, si uno quiere una menor verbosidad y aún mantiene al constructor con su semántica "estándar", uno podría crear un método de fábrica:

activeThreads.add( CustomThread.newStartedThread() );


Por motivos 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. Vea las Técnicas de Construcción Segura de Brian Goetz para más información.


Supongo que quieres hacer esto para que tu código sea menos detallado; en lugar de decir

Thread t = new CustomThread(); t.start(); activeThreads.add(t);

solo puedes decir

activeThreads.add( new CustomThread() );

También me gusta tener menos verborrea, pero estoy de acuerdo con los otros encuestados en que no debes 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 convincente cuando trabajas solo, pero eventualmente 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 el 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.


También verá problemas extraños si la clase Thread es aún más subclasificada. 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.