Buscar
Social
Ofertas laborales ES

Foro sobre Java SE > Problema con hilos y swing.

Hola a todos,
estoy intentando hacer un cronómetro con 3 botones "Start" (empieza a contar), "Stop" (para de contar, cuando pasa a ser un boton Continuar para continuar sobre esa misma cuenta ) y "Reset" (pone el cronómetro a 0). Entonces lo estoy haciendo con un simple hilo (Thread) a parte del hilo de la interfaz principal claro. Creo una clase anónima Thread dentro de mi JDialog donde tengo implementado este cronómetro, sobrescribo el método run() y dentro de el pongo un bucle donde llamo a un método que calcula el segundo siguiente (he puesto también centésimas). Pego dicho código :

public void empezar(){
this.arrancado=true;
this.jButtonStart.setEnabled(false);
this.jButtonReset.setEnabled(false);
// Con hilos
this.hilo = new Thread(){
@Override
public void run(){
try {
while(true){
if(pausado)
pausar();
sleep(10);
dibujaCronometro();
}
} catch (InterruptedException ex) {
Logger.getLogger(CronometroJPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
this.hilo.start();
}

Hasta aquí todo bien....el problema me viene cuando quiero implementar el botón de parar....pongo un this.hilo.wait(); // hilo es una variable de instancia de tipo Thread, y me bloquea el hilo principal que dibuja, AWT-EventQueue-0, yo pensaba que si llamaba al wait de dicho hilo bloquearía dicho hilo.
¿Qué solucuiones me proponéis?
Lo he conseguido llamando al wait() dentro del run() sobrescrito de la clase Thread, pero no entiendo por qué no va lo otro.
También me da un warning al tener el sleep() dentro de un bucle...pero lo he mirado por ahi y los ponen ahí...
Gracias y disculpar por el tocho.
Espero respuestas.
Saludos.

diciembre 29, 2012 | Unregistered Commentershao

No funciona por la razón que se resalta en negrita, más abajo.
Ese método pausar() pertenece a otra clase diferente, luego un wait() declarado en su bloque de código, se ejecuta usando como monitor la clase donde se declara pausar(), por lo tanto detiene la tarea donde se ejecuta la instancia de esa clase, no la tarea de la clase donde se llama a ese método.

http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()
public final void wait()
throws InterruptedException
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:

synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}

This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.
Throws:
IllegalMonitorStateException - if the current thread is not the owner of the object's monitor.
InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.
See Also:
notify(), notifyAll()

diciembre 29, 2012 | Registered Commenterchoces