子線程阻塞的一個解決方案

    首先,說下我的需求。我有一個子線程對局域網某個主機進行試探連接,用的是開源項目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 跳出死循環,結束這個線程。

 


 

         

 

發佈了15 篇原創文章 · 獲贊 0 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章