java - showoptiondialog - personalizar joptionpane
¿Es legal llamar al método de inicio dos veces en el mismo Tema? (10)
El siguiente código lleva a java.lang.IllegalThreadStateException: Thread already started
cuando llamé al método start()
segunda vez en el programa.
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
Esto sucede la segunda vez que se llama a updateUI.start()
. Lo he revisado varias veces y se ha invocado el hilo y se ejecuta por completo antes de pulsar updateUI.start()
.
Llamar a updateUI.run()
evita el error pero hace que el hilo se ejecute en el hilo de UI (el hilo de llamada, como se menciona en otras publicaciones en SO), que no es lo que quiero.
¿Se puede iniciar un hilo solo una vez? Si es así, ¿qué hago si quiero ejecutar el hilo nuevamente? Este hilo en particular está haciendo algunos cálculos en el fondo, si no lo hago en el hilo de lo que está hecho en el hilo de la interfaz de usuario y el usuario tiene una espera irracionalmente larga.
¿Se puede iniciar un hilo solo una vez?
Sí. Puedes comenzarlo exactamente una vez.
Si es así, ¿qué hago si quiero ejecutar el hilo de nuevo? Este hilo en particular está haciendo algunos cálculos en el fondo, si no lo hago en el hilo de lo que está hecho en el hilo de la interfaz de usuario y el usuario tiene un irrazonable larga espera.
No ejecute el Thread
nuevo. En su lugar crea Runnable y publícalo en Handler of HandlerThread . Puede enviar múltiples objetos Runnable
. Si desea enviar datos de vuelta a UI Thread, con su Runnable
run()
, publique un Message
en Handler
de UI Thread y procese handleMessage
Consulte esta publicación para obtener un código de ejemplo:
Sería realmente feo, pero puedes Ajustar un hilo con otro hilo para ejecutar el código de nuevo, pero solo esto es lo que realmente debes hacer.
Tuve que arreglar una fuga de recursos que fue causada por un programador que creó un Thread pero en lugar de iniciar () ing, llamó directamente al método run (). Así que evítelo, a menos que realmente sepa realmente qué efectos secundarios causa.
De la especificación API de Java para el método Thread.start
:
Nunca es legal comenzar un hilo más de una vez. En particular, un hilo no puede reiniciarse una vez que se ha completado la ejecución.
Además:
Lanza:
IllegalThreadStateException
: si el hilo ya se inició.
Entonces sí, un Thread
solo se puede iniciar una vez.
Si es así, ¿qué hago si quiero ejecutar el hilo nuevamente?
Si un Thread
necesita ejecutarse más de una vez, entonces uno debe hacer una nueva instancia del Thread
y llamar a start
en él.
Es como dijiste, un hilo no se puede iniciar más de una vez.
Directamente de la boca del caballo: Especificación API de Java
Nunca es legal comenzar un hilo más de una vez. En particular, un hilo no puede reiniciarse una vez que se ha completado la ejecución.
Si necesita volver a ejecutar lo que esté sucediendo en su hilo, tendrá que crear un nuevo hilo y ejecutarlo.
Exactamente correcto. De la documentación :
Nunca es legal comenzar un hilo más de una vez. En particular, un hilo no puede reiniciarse una vez que se ha completado la ejecución.
En términos de lo que puede hacer para el cálculo repetido, parece que podría usar el método SwingUtilities invokeLater . Ya está experimentando con llamar a run()
directamente, lo que significa que ya está pensando en usar un Runnable
lugar de un Thread
bruto. Intenta usar el método invokeLater
solo en la tarea Runnable
y mira si eso se ajusta un poco mejor a tu patrón mental.
Aquí está el ejemplo de la documentación:
Runnable doHelloWorld = new Runnable() {
public void run() {
// Put your UI update computations in here.
// BTW - remember to restrict Swing calls to the AWT Event thread.
System.out.println("Hello World on " + Thread.currentThread());
}
};
SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");
Si reemplaza esa llamada println
con su cálculo, podría ser exactamente lo que necesita.
EDITAR: siguiendo el comentario, no había notado la etiqueta de Android en la publicación original. El equivalente a invokeLater en el trabajo de Android es Handler.post(Runnable)
. De su javadoc:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* @param r The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
Por lo tanto, en el mundo Android, puede usar el mismo ejemplo que el anterior, reemplazando Swingutilities.invokeLater
con la publicación correspondiente en un Handler
.
La respuesta recién llegada explica por qué no debes hacer lo que estás haciendo. Aquí hay algunas opciones para resolver su problema real.
Este hilo en particular está haciendo algunos cálculos en el fondo, si no lo hago en el hilo de lo que está hecho en el hilo de la interfaz de usuario y el usuario tiene una espera irracionalmente larga.
Vuelca tu propio hilo y usa AsyncTask
.
O crea un hilo nuevo cuando lo necesites.
O configure su hilo para operar fuera de una cola de trabajo (por ejemplo, LinkedBlockingQueue
) en lugar de reiniciar el hilo.
Lo que debe hacer es crear un ejecutable y envolverlo con un nuevo subproceso cada vez que desee ejecutar Runnable. Sería realmente feo, pero puedes Ajustar un hilo con otro hilo para ejecutar el código de nuevo, pero solo esto es lo que realmente debes hacer.
Sí, no podemos comenzar a ejecutar el hilo. Lanzará IllegalThreadStateException en tiempo de ejecución, si el hilo ya se inició.
¿Qué sucede si realmente necesita iniciar el hilo? Opción 1) Si un hilo necesita ejecutarse más de una vez, entonces debe hacer una nueva instancia del hilo y comenzar la llamada.
Volver a utilizar un hilo es una acción ilegal en la API de Java. Sin embargo, podría envolverlo en un implemento ejecutable y volver a ejecutar esa instancia nuevamente.
No , no podemos volver a iniciar Thread, al hacerlo lanzaremos runtimeException java.lang.IllegalThreadStateException. >
El motivo es que una vez que el método run () se ejecuta con Thread, entra en estado muerto.
Tomemos un ejemplo: pensar en comenzar de nuevo el hilo y llamar al método start () (que internamente llamaremos al método run ()) para nosotros es algo así como pedirle al hombre muerto que se despierte y ejecute. Como, después de completar su vida, la persona queda en estado muerto.
public class MyClass implements Runnable{
@Override
public void run() {
System.out.println("in run() method, method completed.");
}
public static void main(String[] args) {
MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
thread1.start();
thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
}
}
/ * OUTPUT en el método run (), método completado. Excepción en el hilo "principal" java.lang.IllegalThreadStateException en java.lang.Thread.start (Fuente desconocida) * /