как уничтожить поток, приостановить / приостановить поток, возобновить / запустить снова создать поток? - PullRequest
2 голосов
/ 21 марта 2011

Эй, ребята Я использую runnable вне oncreate в моем приложении для Android, где я использовал поток, чтобы установить прогресс ProgressBar. Чего я не знаю, так это как остановить / уничтожить поток, когда нажата кнопка остановки, так как thread.stop не является методом, и как от этого отказаться, как даже уничтожить поток.

Я знаю, что я должен сделать некоторые методы и члены в runnable, но я точно не знаю, что ??

Ответы [ 4 ]

3 голосов
/ 22 марта 2011

Thread.stop() больше не используется, поскольку считается опасным: http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html.

Вы должны позволить естественному завершению потока в результате изменения переменной.Ссылка также дает несколько советов о том, как этого добиться.

public class MyThread extends Thread {

    private boolean threadDone = false;

    public void done() {
        threadDone = true;
    }

    public void run() {
        while (!threadDone) {
            // work here
            // modify common data
        }
    }

}

Предупреждение: убедитесь, что вы используете защищенный блок в циклическом коде,метод, который блокирует сам себя, или Thread.sleep(..).Thread.sleep - самый примитивный из них, если вы не понимаете защищенные блоки, но это будет работать.Вы также можете ждать вечно и использовать механизм прерываний для отмены потока, который выбрасывается как InterruptedException в блоке try-catch, когда вы используете wait или sleep.Для этого используйте !Thread.currentThread().isInterrupted() в качестве условия защиты цикла, затем используйте объект Thread и вызовите thread.interrupt().

2 голосов
/ 22 марта 2011

Чтобы управлять потоком Java, вы должны добавить методы к объекту, которые могут вызываться другими объектами, которые устанавливают переменные, читаемые вашим методом run(). Вы не предоставляете много информации о том, что именно делаете, но вот возможный пример:

public class ProgressBarUpdater implements Runnable{
    private volatile boolean paused = false;
    private volatile boolean finished = false;

    /* other fields, constructor etc. */

    public void run(){
        while(!finished){
            updateProgressBar();

            while(paused && !finished){
                try{
                    Thread.sleep(1000); //Busy wait - should really use wait/notify, but that's another lesson
                }
                catch(InterruptedException e){

                }
            }
        }
    }

    public synchronized void pauseProgressBar(){
        paused = true;
    }

    public synchronized void unPauseProgressBar(){
        paused = false;
        //call notify() here when you switch to wait/notify.
    }

    public void stopProgressBar(){
        finished = true;
        //call notify() here too.
    }
}

Возможно, вы захотите использовать более надежную синхронизацию с управляющими переменными и, как уже упоминалось в комментариях, ждать / уведомлять, а не занятое ожидание.

Использовать так:

ProgressBarUpdater pbu = new ProgressBarUpdater();

Thread t = new Thread(pbu);

t.start();
Thread.sleep(10000); //let the progress bar run for ten seconds.

pbu.pauseProgressBar();
Thread.sleep(10000); //pause it for ten seconds.

pbu.unPauseProgressBar();
Thread.sleep(10000); //restart for another ten seconds.

pbu.stopProgressBar(); //stop progress bar.
2 голосов
/ 22 марта 2011

У вас есть несколько параметров, и они зависят от того, как вы определяете различные состояния вашего потока.

Поток эффективно останавливается при выходе из метода run ().

To "Пауза "и" возобновить "выполнение потока вы можете использовать wait () и notify ().

Чтобы проиллюстрировать это, вот краткий пример:

class MyThread implements Runnable {
    private boolean keepRunning = false;
    private boolean isPaused = false;

    public void run() {
        keepRunning = true;
        try {
            while (keepRunning) {
                // do stuff here
                if (isPaused) {
                    synchronized (this) {
                        // wait for resume() to be called
                        wait();
                        isPaused = false;
                    }
                }
            }
        } catch (Exception ex) {
            // do stuff
        }
    }

    // note that as-is this won't do anything to a paused thread until
    // it is resumed.
    public void stop() {
        keepRunning = false;

    }

    public void pause() {
        isPaused = true;
    }

    public synchronized void resume() {
        // notify anybody waiting on "this"
        notify();
    }
}
0 голосов
/ 22 марта 2011

Пусть другой поток периодически проверяет логический флаг (isCancelled или что-то в этом роде). Изначально это ложь.

Из кода кнопки остановки установите для этого значения значение true.

Когда ваш поток в следующий раз проверит флаг и обнаружит, что он имеет значение true, поток должен убить себя.

...