it-swarm.com.de

Wie kann ich einen Thread anhalten und wieder aufnehmen?

Ich gebe an, dass ich über Thread gelesen habe, aber ich habe es nie benutzt. Also bitte ich dich :)

Ich habe zwei Threads: A und B, wobei A die GUI verwaltet und B die Logik verwaltet.

Ich würde mit A beginnen.

Dann, wenn A die GUI zeichnet, würde ich es pausieren, um B zu warten, die einen Punkt X in Run-Methode erreichen.

Und wenn B die X-Punkt-in-Run-Methode erreicht, pausiere ich B und setze A fort.

A und B teilen sich eine Variable, um die GUI und die Logik zu verwalten ...

Kann ich es schaffen? wenn ja wie :)

40
Teo

Mit den Methoden wait() und notify() :

wait() - Lässt den aktuellen Thread warten, bis ein anderer Thread die Methode notify() oder die Funktion notifyAll() Methode für dieses Objekt.

notify() - Aktiviert einen einzelnen Thread, der auf dem Monitor dieses Objekts wartet.

23
Dineshkumar

Sie können Threads mit den Methoden wait und notify der Object-Klasse blockieren, es kann jedoch schwierig sein, die richtigen Schritte auszuführen. Hier ist ein Beispiel innerhalb einer Endlosschleife in einem 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 {
                        synchronized (pauseLock) {
                            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
        }
    }
};

(Weitere Informationen darüber, warum wir wie oben gezeigt synchronisieren müssen, während wir wait und notifyAll aufrufen, finden Sie unter das Java Tutorial zu diesem Thema .)

Wenn ein anderer Thread die pause() -Methode dieses Runnable aufruft, wird der Thread, der das Runnable ausführt, blockiert, wenn er an den Anfang der while-Schleife gelangt.

Beachten Sie, dass es nicht möglich ist, einen Thread an einem beliebigen Punkt anzuhalten. Sie müssen den Thread regelmäßig überprüfen, ob er anhalten und sich selbst blockieren soll, wenn dies der Fall ist.

15
megaflop

Ich würde erwarten, dass Sie den GUI-Thread nicht anhalten müssen. Das Betriebssystem kümmert sich darum und muss bereit sein, zu reagieren, falls der Benutzer etwas unternimmt.

Ein weiterer Gedanke ist, sicherzustellen, dass die gemeinsam genutzten Variablen zwischen den beiden Threads ordnungsgemäß synchronisiert sind. Ich habe kürzlich versucht, eine diesbezügliche Frage zu beantworten, siehe hier .

4
Stochastically

sie können ein CountDownLatch verwenden. Wenn Thread A warten muss, bis Thread B countDownLatchInstance.await(); aufruft. Wenn B den X-Punkt erreicht, wird countDownLatchInstance.countDown() aufgerufen. Zulassen, dass A seinen Ausführungsfluss fortsetzt.

Wenn du sagst

A verwaltet die GUI

Ich hoffe, Sie verweisen nicht auf die UI/Main Thread

,

3
Blackbelt

Auf diese Weise habe ich das Warten des Threads und die Benachrichtigung erhalten, dass für mich gearbeitet wird:

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();
            }
        }
    }
}

public class MyThread extends 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);
    }
}

Wenn ich dann den Knopf drücke, wacht der andere Thread auf, führt eine Runde aus und wartet auf ein erneutes Klicken.

1
lfvv

Das Grundelement Java zum Anhalten und Fortsetzen eines Threads ist veraltet. Sehen Sie sich dies an, um herauszufinden, wie Sie am besten das erreichen können, was Sie benötigen - http://docs.Oracle.com/javase/ 7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html Überprüfen Sie, wie Sie das Äquivalent von Suspend & Resume durchführen können

Was soll ich anstelle von Thread.suspend Und Thread.resume Verwenden?

Wie bei Thread.stop Besteht die vorsichtige Vorgehensweise darin, dass der "Ziel-Thread" eine Variable abfragt, die den gewünschten Status des Threads angibt (aktiv oder ausgesetzt). Wenn der gewünschte Status angehalten ist, wartet der Thread mit Object.wait. Wenn der Thread wieder aufgenommen wird, wird der Ziel-Thread mit Object.notify Benachrichtigt.

Beispielcode wird in derselben Antwort angegeben, um dies zu erreichen.

0
user93353