子线程阻塞的一个解决方案

    首先,说下我的需求。我有一个子线程对局域网某个主机进行试探连接,用的是开源项目JCIFS类,该类并没有对连接超时时间的设置,只是在很长时间连不上后会报出connect timeoutwarning,这并不是我想要的。因为试想,用户可能会在一段时间连不上后选择退出该Activity,那么此时后台还在连接,当连接上后会在子线程通过handler将数据传回,或者连接不上后通过handler传一个消息,以弹出dialog提示无法连上。可是,此时Activity已经退出,数据或者dialog所依存的Activity已经退出,这样的话就会报异常(具体什么异常忘记了)

    接下来,说下我是怎么解决的。我声明一个boolean类型的成员变量isExited,默认为false

该变量在该ActivityonDestroy时变为true。当需要handler传消息给主线程时先判断isExitedfalse还是true,如果false才进行相应操作。子线程不管他,让他自行运行结束。

    你可能会有这样的疑问,这样Activity退出时并不能结束子线程啊?当然,我一开始也试着去结束他,控制他同主线程一起结束。可是,要知道,Java中线程之间是平等的,所谓的主线程子线程只是一个区分而已,一个线程并不能强制的控制另外一个线程何时结束,最好的结束方式就是让子线程的run方法运行完毕。这也就是Thread.stop()Thread.destroy()不能使用的原因。另外,网上有说通过InterruptedException来结束的方案,对于我这个例子却是不适用的,因为只有Thread.sleep()或Thread.wait()被打断时才会抛出该异常,对于阻塞的操作,无法适用。

   以下是我在网上查到的三种结束方式:

      1.线程正常执行完毕,正常结束 ,线程正常执行完毕, 也就是让 run 方法执行完毕,该线程就会正常结束。

      2.监视某些条件,结束线程的不间断运行 ,监视某些条件, 然而,常常有些线程是伺服线程。它们需要长时间的运行,只有在外部某些条件满足的情况 下,才能关闭这些线程。 通常,它们执行在一个 while(true)的死循环中。如:

       

	@Override
	publicvoid run() {
		while (true) {
			someWork();
			if (finished) {
				break;
			}
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) { /* TODO 自动生成 catch 块 * */
				e.printStackTrace();
			}
		}
	}

      3.捕获 InterruptedException 运行时异常,中断当前线程 , 运行时异常, 有些执行伺服任务的线程,在 while(true)这样的死循环内部,是一个阻塞中的方法。此时, 就不能采用第二种方法了。因为,当该方法没有返回时,该线程一直处于阻塞当中,根本无 法执行其他语句。 此时,就需要调用该线程的 interrupt 方法,产生一个 InterruptedException 运行时异常,是 阻塞中的那个方法抛出这个异常,从而让我们有机会结束这个线程的执行。如:

         

	@Override 
	 public void run() { 
		while(true){ 
			try { 
				someMethod();//此处为阻塞的方法
				} catch (InterruptedException e1) { 
					thrownew RuntimeException(); //或者 break; 
				}
			someWork(); 
			}
	 	}
	 }

 一个外部的 Thread 对象指向这个线程。需要结束这个线程时,只需要调用 thread 对象的 interrupt() 方法,就会在 someMethod()这条语句中产生一个 InterruptedException 异常,从而结束该线程的阻塞状态,通过抛出异常,或者 break 跳出死循环,结束这个线程。

 


 

         

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值