今天早上一来就被人追杀,说我的WFDMonitorThread没有正常退出,测试中导致了一系列的问题。这里,就总结一下线程如何正确退出,同时理解break和return的正确用法。
我写的线程如下:
class WfdMonitorThread extends Thread{
public WfdMonitorThread(){
super("WfdMonitor");
}
public void run(){
Log.d(TAG,"WfdMonitor havestarted");
for(;;){
String eventStr =mWfdManager.wfdClientWaitForEvent();
if("stopThread".equals(eventStr)){
Log.d(TAG,"WfdMonitorstop");
break;//这里也可以用return,对这个程序来说,效果是一样的
}
if(null != eventStr){
Intent intent = newIntent(eventStr);
mContext.sendBroadcast(intent);
}
}
}
这个线程的意思是调用 wfdClientWaitForEvent() 返回字符串,如果返回的字串是 stopThread,那么就退出线程。我们知道线程关闭是,执行完run()方法体的内容后就自动关闭。线程启动可以用如下的方法:
public voidstartWfdMonitoring(){
new WfdMonitorThread().start();
}
上面这段程序这样写有没有什么问题呢?执行时会出现如下的log:
(121220_19:55:59.671)D/WfdMonitor( 1027): WfdMonitor stop
已经打印WfdMonitor stop,但是后面还会不断打印
(121220_19:55:59.764)E/WfdService( 149): wfd_client_wait_for_event()
(121220_19:55:59.764)D/ ( 149): wfd_client_wait_for_event
(121220_19:55:59.764)E/WfdService( 149): wfd_client_wait_for_event()
(121220_19:55:59.764)D/ ( 149): wfd_client_wait_for_event
这说明使用break并没有退出for循环,更没有退出run函数,所以线程没有退出成功?我第一反应是这样的,但是事实证明不是的,后面会用小程序证明。关于
java break,cotinue,return可以参考
http://blog.csdn.net/okjesse/article/details/2719174。return语句的作用:
(1)return从当前的方法中退出,返回到该调用的方法的语句处,继续执行
(2)return返回一个值给调用该方法的语句
break语句的作用:
(1)只能在循环体内和switch语句内使用break语句。
(2)当break出现在循环体中的switch语句体内时,其作用只是跳出该switch语句体。
(3)在循环结构中,应用break语句使流程跳出本层循环体,从而提前结束本层循环
Continue语句的作用:
continue语句作用是结束本次循环,即跳过本次循环体中余下尚未执行的语句,接着再一次进行循环的条件判定。
好,接着测试一下我上面的这种写法在能否让线程正常退出。
public class wfdMonitorThread extends Thread{
public wfdMonitorThread(){
super("WfdMonitor");
}
public static void main(String[] args)throws Exception{
System.out.println("WfdMonitor have started");
new wfdMonitorThread().start();
}
public void run(){
System.out.println("WfdMonitor have started");
int i=0;
for(;;){
i++;
//String eventStr = "stopThread";
System.out.println("WfdMonitor stop4444444");
if(i>3){
System.out.println("WfdMonitor stop");
return;
// break;
}
else
System.out.println("WfdMonitor stop2222222222");
}
}
在eclipse中执行这个程序 ,打印出的log如下:
WfdMonitor have started
WfdMonitor stop4444444
WfdMonitor stop2222222222
WfdMonitor stop4444444
WfdMonitor stop2222222222
WfdMonitor stop4444444
WfdMonitor stop2222222222
WfdMonitor stop4444444
WfdMonitor stop
所以,是正常退出的。换成return,效果也是一样。
那么为什么会没有正常退出线程呢?wfdMonitorThread退出的条件是wfd_client_wait_for_event()返回的字串为WFD-RTSP-TERMINATE。我看了一下log,发现wfdMonitorThread启动了三次,却只有其中的两个线程收到WFD-RTSP-TERMINATE并退出,另外还有一个线程并没有收到WFD-RTSP-TERMINATE,所以一直没有退出,
故一直不停地打这句log:
(121220_19:55:59.764)E/WfdService( 149):wfd_client_wait_for_event()
(121220_19:55:59.764)D/ ( 149):wfd_client_wait_for_event
所以,问题是我这边线程没有正常退出,但是原因是为什么没有发WFD-RTSP-TERMINATE上来。
至此,问题得到定位并解决。
通过这个问题,更加深入地理解了线程的执行和退出,以及break、continue和return的用法及作用。