Android 为什么线程不停止?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1204012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:46:49  来源:igfitidea点击:

Why isn't the thread stopping?

androidmultithreading

提问by montooner

My service spawns a new thread, and stops it according to the typically recommended javamethod of interrupt()'ing. When I stop the service, I stop the thread in onDestroy(). The service is stopped, and the interrupt code is reached. However, soon enough the thread restarts from the beginning of the Runnable.

我的服务产生一个新线程,并根据通常推荐的中断()方法的java方法停止它。当我停止服务时,我会在 onDestroy() 中停止线程。服务停止,到达中断码。但是,线程很快就会从 Runnable 的开头重新启动。

public class DoScan extends Service {
    public volatile Thread runner;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        startThread();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.onDestroy");
        stopThread();
    }


    public synchronized void startThread(){
        if(runner == null){
            android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.startthread");     
            runner = new Thread(new ScanningThread());
            runner.start();
        }
    }
    /* use a handler in a loop cycling through most of oncreate.
     * the scanningthread does the work, then notifies the svc's uithread
     */

    public synchronized void stopThread(){
        if(runner != null){
            android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.stopthread");
            Thread moribund = runner;
            runner = null;
            moribund.interrupt();
            android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "interrupted?" + moribund.isInterrupted());
        }
    }
        }

回答by Lucas S.

I think the safest way is to have a flag so the thread checks for it inside its main loop.

我认为最安全的方法是有一个标志,以便线程在其主循环内检查它。

class ScanningThread extends Thread {
    // Must be volatile:
    private volatile boolean stop = false;

    public void run() {
        while (!stop) {
            System.out.println("alive");
        }
        if (stop)
            System.out.println("Detected stop");
    }

    public synchronized void requestStop() {
        stop = true;
    }
}

public synchronized void startThread(){
    if(runner == null){
        android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.startthread");         
        runner = new ScanningThread();
        runner.start();
    }
}

public synchronized void stopThread(){
    if(runner != null){
        android.util.Log.v("@@@@@@@@@@@@@@@@@@@@", "DoScan.stopthread");
        runner.requestStop();
        runner = null;
    }
}

回答by Michael Aaron Safyan

The problem is that your thread needs to cooperate by periodically checking for interruption and exiting if the thread has been interrupted. Unless you place something along the lines of the following in your thread...

问题是您的线程需要通过定期检查中断并在线程被中断时退出来进行协作。除非你在你的线程中放置了以下内容......

 // Processing...
 if ( Thread.interrupted() ){
    return;
 }
 // More processing...
 try{
    Thread.sleep(sleeptime);
 }catch(InterruptedException interrupt){
    return;
 }
 // Rinse and repeat...

...your thread will just ignore the fact that it has been interrupted. The method proposed by Lucas S. is essentially identical, except that using interruption will generate an exception if the thread is blocked, whereas under Lucas S.'s method, you might have to wait indefinitely for the thread to quit.

...您的线程将忽略它已被中断的事实。Lucas S. 提出的方法本质上是相同的,只是使用中断会在线程被阻塞时产生异常,而在 Lucas S. 的方法下,您可能需要无限期地等待线程退出。

回答by Prashast

Interrupting a thread throws an exception in the thread, it does not necessarily stop it. You should catch that exception and then do the clean up in thread before exiting (provided, you need to exit!).

中断线程会在线程中抛出异常,它不一定会停止它。您应该捕获该异常,然后在退出之前在线程中进行清理(前提是您需要退出!)。