java 多線程在android 開發中的使用頻率很高,用一個形象的比喻來演示線程的生命週期: 和人有生老病死同樣,線程也有它完整的生命週期: 1. 新生(NEW):The thread has been created, but has never been started. 表明線程的對象已經被初始化,但還沒有運行start() 方法,一樣run()也未執行。 2. 就緒(RUNNABLE ):表示線程能夠執行,但尚未執行,何時執行run()方法得看系統的調度策略,好比start()執行,run()未執行,在這個階段系統要爲線程分配運行須要的空間如棧、程序計數器,或者線程在wait()中被激活。 3. 運行(RUNNING):根據系統調度策略,該線程獲取CPU控制權,進入運行狀態,執行run()方法. 4.阻塞(BLOCKED):運行狀態下的線程可能進入阻塞狀態,好比等待某個同步鎖(Syncronize),等待wait()中等待notify(),sleep(time); 5.死亡(TERMINATED ):The thread has been terminated. 線程的正式結束方式,run方法執行完畢並返回。 在Thread中應該如何更好的控制整個生命週期,咱們先來看看Thread類代碼,下面的方法會影響到線程的生命週期,爲了方便省略了實現細節: package java.lang; public class Thread{ public void start(); // 線程的啓動 public void run(); // 線程體 public void stop(); // 已廢棄 public void resume(); // 已廢棄 public void suspend(); // 已廢棄 public static void sleep(long millis); // 在指定的毫秒數內讓當前正在執行的線程休眠 public static void sleep(long millis, int nanos); // 同上,增長了納秒參數 public boolean isAlive(); // 測試線程是否處於活動狀態 public void interrupt(); // 中斷線程 public boolean isInterrupted(); // 測試線程是否已經中斷 public static boolean interrupted(); // 測試當前線程是否已經中斷 public void join() throws InterruptedException; // 等待該線程終止 public void join(long millis) throws InterruptedException; // 等待該線程終止的時間最長爲 millis 毫秒 public void join(long millis, int nanos) throws InterruptedException; // 等待該線程終止的時間最長爲 millis 毫秒 + nanos 納秒 } 重點:停滯狀態 1.經過sleep(millis)使線程進入休眠,該方法在指定的時間內沒法被喚醒。 2.經過wait() 暫停線程,除非收到notify()或notifyAll()消息,不然不會變回可執行狀態。wait()和notify()兩個函數都是Object的 一部分,不像sleep()那樣屬於Thread,這是由於兩個函數會取用對象的機鎖,而機鎖正是每一個繼承自Object對象都擁有的。如此一來咱們能夠 把wait()置於任何同步函數內,也只能在同步函數中調用wait()。sleep()、suspend()、resume()能夠在全部非同步函數中 使用,由於它們不會取用機鎖。 3. 線程正在等待某個IO動做完成。 4.線程正嘗試調用一個同步對象,但還沒有取得該對象機鎖 syncronized()。 sleep()和wait()均可以使線程進入中止狀態,兩者的實現機理不同: 一、sleep()不會釋放鎖,其餘線程不能夠訪問同步監視器;線程wait()會釋放鎖,其餘線程能夠訪問同步監視器---最主要區別; 二、參數不同,wait()能夠無參數----等待notify()來喚醒,也能夠設定一個int值,時間一到天然醒來,進入runnable狀態,同時收回對象鎖;sleep(int)必須有一個int型參數,時間到後進入runnable狀態;兩種狀況都不必定能夠立刻執行,而是進入可運行線程的隊列中,什麼時候執行 根據CPU分配機制決定執行時間; 三、sleep()是Thread的方法,wait()是Object的方法; 下面的例子表現了一個完整的線程生命週期: import android.app.Activity; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.AudioTrack; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Looper; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.SeekBar; import android.widget.Toast; public class AUDIOBUFFERActivity extends Activity { /** Called when the activity is first created. */ Button btnstart, btnStop, btnExit; static final String LOG_TAG = "TestMultiThread"; private WorkingThread mWorkingThread; public Object syncobj; public Boolean mStop; public Boolean mCanDo; public ClickEvent mClickEvent; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setTitle("test thread"); btnstart = (Button)AUDIOBUFFERActivity.this.findViewById(R.id.btnRecord); btnStop = (Button)AUDIOBUFFERActivity.this.findViewById(R.id.btnStop); btnExit = (Button)AUDIOBUFFERActivity.this.findViewById(R.id.btnExit); mClickEvent = new ClickEvent(); btnStop.setOnClickListener(mClickEvent); btnstart.setOnClickListener(mClickEvent); btnExit.setOnClickListener(mClickEvent); syncobj = new Object(); mStop = true; mCanDo = true; mWorkingThread = new WorkingThread(); mWorkingThread.start(); } class ClickEvent implements View.OnClickListener { @Override public void onClick(View v) { if (v == btnstart) { if(mStop) { mStop = false; requestRun(); } } else if (v == btnStop) { mStop = true; } else if (v == btnExit) { mCanDo = false; AUDIOBUFFERActivity.this.finish(); } } } public void changeToWait() { synchronized(mWorkingThread) { try { mWorkingThread.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void requestRun() { synchronized(mWorkingThread) { mWorkingThread.notify(); } } class WorkingThread extends Thread { public void run() { try { while(mCanDo) { if(mStop) { changeToWait(); } synchronized(syncobj) { sleep(500); } Log.d(LOG_TAG, "WorkingThread in run"); } } catch (Throwable t) { Log.d(LOG_TAG, "error happened==t:"+t.toString()); } } }; }