Android : 執行緒的結束,掛起和恢復(下)

yangxi_001發表於2016-05-27

二. 執行緒的掛起與恢復

   同樣, Android執行緒類也提供了一些公共方法去掛起和恢復執行緒:

final void resume()                                       

This method is deprecated. Used with deprecated method suspend

final void suspend()

This method is deprecated. May cause deadlocks

       同樣不幸的是,通過說明我們可以看到,這些方法Android也是不推薦使用的,經過筆者試驗,這些方法也沒有效果。那我們如何去掛起和恢復執行緒呢?筆者又來救贖了。

     Android的類基本都是繼承於Object類。此類可以說是Android類的祖先了。如果把Android類比喻為一個生物界,則Object類就是當初生命誕生時候的那個單細胞。

       我們可以發現Object類提供了幾個方法 

         final void notify()

Causes a thread which is waiting on this object's monitor (by means of calling one of the wait() methods) to be woken

final void notifyAll()

Causes all threads which are waiting on this object's monitor (by means of calling one of the wait() methods) to be woken

final void wait()

Causes the calling thread to wait until another thread calls the notify() ornotifyAll() method of this object

 

       通過說明我們可以知道,wait方法可以讓正在呼叫的執行緒處於等待狀態,直到其他執行緒呼叫了該物件的notify 或者notifyAll,而notify notifyAll方法則是用於喚醒處於等待中的執行緒。

       同樣,執行緒類也是繼承於Object類,但是執行緒類是一個比較特殊的類,有自己獨立的棧機制來處理其方法,引數和區域性變數。通過實驗,筆者發現,雖然執行緒類繼承於Object類,但是卻不能通過waitnotify方法掛起喚醒執行緒。而要實現上述動作,必須去間接地實現,即在自定義執行緒類中建立一個Object物件,然後通過對該Object的相關操作實現執行緒的掛起和喚醒。方法如下:

1.    在自定義執行緒類的例項化過程中建立一個Object物件。

2.    定義一個變數來記錄執行緒的狀態是否掛起,初始化為假。

3.    線上程類中的run函式中的執行緒執行部分找入鍥點來執行下面動作:如果當前狀態變數為假(表示執行緒掛起),則通過1Object物件的wait方法掛起當前執行緒,即執行緒暫停在鍥點位置,如果被喚起,則將從鍥點後繼續執行。

4.    定義一個方法來修改執行緒狀態變數為真,從而達到掛起執行緒的目的。

5.    定義一個方法去喚醒執行緒。判斷如果執行緒狀態變數為真,則修改其為假,然後呼叫1Object物件的notifyAll方法喚醒物件。(notify方法也可以,但是如果自定義執行緒較多時容易造成死鎖)。

綜上,當自定義執行緒執行後我們可以通過4中的方法掛起執行緒,通過5中的方法喚醒執行緒。

 

程式例項 :

class SearchThread extends Thread

   {

      private Object mPauseLock ;

      private boolean mPauseFlag ;   

     

      public SearchThread()

      {

         

          mPauseLock = new Object() ;

          mPauseFlag = false ;

      }

     

      public void onPause()

      {

          synchronized (mPauseLock) {

             mPauseFlag = true;

             }

      }

     

      public void onResume()

      {

          synchronized (mPauseLock) {

             mPauseFlag = false ;

             mPauseLock.notifyAll() ;

             }

      }

            

      private void pauseThread()

      {

          synchronized (mPauseLock) {

             if(mPauseFlag)

             {

                try{

                   mPauseLock.wait() ;

                }catch(Exception e){

                   Log.v("thread", "fails") ;

                }

             }

             }

      }    

 

@Override

      public void run()

    {

       ……

       //---執行緒執行部分,僅僅舉例為了說明-----

         for(int i = 0; i < 100; i++)

      {

          pauseThread() ;

          ……

          for(int j = 0; j < 100; j++)

          {

               pauseThread() ;

               ……

          }

}

       //-----end----------

       ……

      }

}

相關文章