代码之家  ›  专栏  ›  技术社区  ›  montooner

为什么不停线?

  •  3
  • montooner  · 技术社区  · 15 年前

    我的服务生成一个新线程,并根据 typically recommended java 中断方法。当我停止服务时,我停止OnDestroy()中的线程。服务停止,并到达中断代码。但是,很快线程就会从可运行文件的开头重新启动。

    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 回复  |  直到 15 年前
        1
  •  11
  •   Lucas S.    15 年前

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

    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;
        }
    }
    
        2
  •  11
  •   Michael Aaron Safyan    15 年前

    问题是,您的线程需要通过定期检查中断和退出(如果线程被中断)来进行协作。除非你把一些东西沿着下面的线放在你的线程中…

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

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

        3
  •  0
  •   Prashast    15 年前

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