resueltos - hilos en java pdf
¿Cómo pausar y luego reanudar un hilo? (6)
Declaro que leí sobre el hilo, pero nunca lo he usado. Así que te pregunto :)
Tengo dos hilos: A
y B
, donde A
administra la GUI y B
administra la lógica.
Yo empezaría con A
Luego, cuando A
dibuja la GUI, la detengo para esperar a B
que llegue al punto X en el método de ejecución.
Y cuando B
llega al punto X en el método de ejecución, hago una pausa en B
y reanudo A
A
y B
comparten alguna variable para administrar la GUI, y la lógica ...
¿Puedo hacerlo? Si es así, ¿cómo? :)
Esa es la forma en que conseguí el hilo de espera y notifico trabajar para mí
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
MyThread t = new MyThread();
t.lock = lock;
t.run();
while(true){
try {
synchronized (lock) {
lock.wait();
}
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
clase pública MyThread extiende Thread {
Object lock;
@Override
public void run(){
JFrame fr = new JFrame("Anothing");
JButton btn = new JButton("Next");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
synchronized (lock) {
lock.notify();
}
}
});
fr.setLayout(new FlowLayout());
fr.add(btn);
fr.setSize(400, 400);
fr.setVisible(true);
}
}
Luego, cada vez que presiono el botón, el otro hilo se despierta, ejecuta una ronda y espera un nuevo clic.
Espero que no necesite pausar el hilo de la GUI. El sistema operativo se encargará de eso, y debe estar listo para responder en caso de que el usuario haga algo.
Otro pensamiento es asegurarse de que las variables compartidas estén correctamente sincronizadas entre los dos subprocesos. Intenté responder a una pregunta relacionada con eso recientemente, vea here .
La primitiva Java para suspender y reanudar un hilo está en desuso. Vea esto para ver cómo puede lograr mejor lo que necesita: http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html Verifique cómo puede hacer el equivalente de suspender y reanudar
¿Qué debo usar en lugar de
Thread.suspend
yThread.resume
?Al igual que con
Thread.stop
, el enfoque prudente es hacer que el "subproceso objetivo" sondea una variable que indique el estado deseado del subproceso (activo o suspendido). Cuando se suspende el estado deseado, el hilo espera utilizandoObject.wait
. Cuando el hilo se reanuda, el hilo de destino se notifica utilizandoObject.notify
.
El código de ejemplo se da en la misma respuesta para ayudarlo a lograr esto.
Puede bloquear subprocesos utilizando los métodos de wait
y notify
de la clase Object, pero puede ser difícil hacerlo bien. Aquí hay un ejemplo dentro de un bucle infinito en un Runnable:
public class Example implements Runnable {
private volatile boolean running = true;
private volatile boolean paused = false;
private final Object pauseLock = new Object();
@Override
public void run () {
while (running){
synchronized (pauseLock) {
if (!running) { // may have changed while waiting to
// synchronize on pauseLock
break;
}
if (paused) {
try {
pauseLock.wait(); // will cause this Thread to block until
// another thread calls pauseLock.notifyAll()
// Note that calling wait() will
// relinquish the synchronized lock that this
// thread holds on pauseLock so another thread
// can acquire the lock to call notifyAll()
// (link with explanation below this code)
} catch (InterruptedException ex) {
break;
}
if (!running) { // running might have changed since we paused
break;
}
}
}
// Your code here
}
}
public void stop() {
running = false;
// you might also want to interrupt() the Thread that is
// running this Runnable, too, or perhaps call:
resume();
// to unblock
}
public void pause() {
// you may want to throw an IllegalStateException if !running
paused = true;
}
public void resume() {
synchronized (pauseLock) {
paused = false;
pauseLock.notifyAll(); // Unblocks thread
}
}
};
(Para obtener más información sobre por qué necesitamos sincronizarnos como se ilustra arriba mientras notifyAll
wait
y notifyAll
, consulte el tutorial de Java sobre el tema ).
Si otro Thread llama a este método Runnable''s pause()
, el Thread que ejecuta el runnable se bloqueará cuando llegue a la parte superior del bucle while.
Tenga en cuenta que no es posible pausar un hilo en ningún punto arbitrario. Necesita que el subproceso compruebe periódicamente si debe pausarse y bloquearse si es así.
puede utilizar un CountDownLatch
. Cuando el subproceso A tiene que esperar, el subproceso B llamará countDownLatchInstance.await();
Cuando B alcance el punto X, invocará countDownLatchInstance.countDown()
; permitiendo que A continúe su flujo de ejecución.
Cuando tu dices
A gestiona la GUI
Espero que no te refieras a la UI/Main Thread
,