为什么线程没有停止?

时间:2009-07-30 01:27:38

标签: android multithreading

我的服务生成一个新线程,并根据中断()的typically recommended 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());
        }
    }
        }

3 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:11)

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

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

...你的线程将忽略它已被中断的事实。 Lucas S.提出的方法基本相同,只是如果线程被阻塞,使用中断将生成异常,而在Lucas S.的方法下,您可能必须无限期地等待线程退出。

答案 2 :(得分:0)

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