提问人:montooner 提问时间:7/30/2009 更新时间:7/30/2009 访问量:22167
为什么线程不停止?
Why isn't the thread stopping?
问:
我的服务生成一个新线程,并根据通常推荐的 java 方法 interrupt()'ing 停止它。当我停止服务时,我在 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());
}
}
}
答:
0赞
Prashast
7/30/2009
#1
中断线程会在线程中引发异常,它不一定会停止它。您应该捕获该异常,然后在退出之前在线程中进行清理(前提是,您需要退出!
评论
0赞
Fredrik
8/1/2009
实际上,它不会引发异常。如果某些调用检测到它们已被中断,它们会抛出异常,但在大多数情况下,您必须通过检查 Thread.isInterrupted() 来自己进行检测,何时适合中断工作。
13赞
Lucas S.
7/30/2009
#2
我认为最安全的方法是有一个标志,以便线程在其主循环中检查它。
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;
}
}
11赞
Michael Aaron Safyan
7/30/2009
#3
问题在于,您的线程需要通过定期检查中断来协作,如果线程被中断,则退出。除非您在线程中放置类似以下内容的内容......
// Processing... if ( Thread.interrupted() ){ return; } // More processing... try{ Thread.sleep(sleeptime); }catch(InterruptedException interrupt){ return; } // Rinse and repeat...
...您的线程将忽略它已被中断的事实。Lucas S. 提出的方法基本相同,只是如果线程被阻塞,使用中断将产生异常,而在 Lucas S. 的方法下,您可能需要无限期地等待线程退出。
下一个:更新原始活动中的集成进度条
评论