一.概述java
1.含義:線程是操做系統調度的最小單元。緩存
2.特色:線程是一種受限的系統資源。即線程不可無限制的產生且線程的建立和銷燬都有必定的開銷。bash
Q:如何避免頻繁建立和銷燬線程所帶來的系統開銷? A:採用線程池,池中會緩存必定數量的線程,進而達到效果。多線程
3.分類:併發
二.線程形態異步
對於主線程和子線程相信已經很是熟悉了,如今主要學習如下三種形態的線程:ide
1.AsyncTaskoop
a.AsyncTask:一種輕量級的異步任務類。源碼分析
在Android中實現異步任務機制有兩種方式:Handler和AsyncTask。post
- Handler機制存在的問題:代碼相對臃腫;多任務同時執行時不易精確控制線程。
- 引入AsyncTask的好處:建立異步任務更簡單,直接繼承它可方便實現後臺異步任務的執行和進度的回調更新UI,而無需編寫任務線程和Handler實例就能完成相同的任務。
b.AsyncTask是抽象的泛型類,其組成成員有:
Params
:表示執行AsyncTask須要傳入的參數,可用於在後臺任務中使用;Progress
:表示後臺任務執行的進度;Result
: 表示後臺任務的返回結果的類型;//含義:在執行AsyncTask時不須要傳入參數給後臺任務、使用整型數據來做爲進度顯示單位,最後使用布爾型數據來反饋執行結果
public abstract class AsyncTask<Void, Integer, Boolean>
複製代碼
onPreExecute()
:
doInBackground(Params…params)
:
publishProgress(Progress...)
方法onProgressUpdate(Progress…values)
:
publishProgress(Progress...)
以後該方法會被調用onPostExecute(Result result)
:
onCancelled()
:
execute(Params...params)
cancel(booleanmayInterruptIfRunning)
好比自定義一個AsyncTask,來模擬一個下載任務:
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
@Override//初始化一個ProgressDialog
protected void onPreExecute() {
progressDialog.show();
}
@Override//具體的下載邏輯
protected Boolean doInBackground(Void... params) {
try {
while (true) {
int downloadPercent = doDownload();
publishProgress(downloadPercent);
if (downloadPercent >= 100) {
break;
}
}
} catch (Exception e) {
return false;
}
return true;
}
@Override//顯示當前的下載進度
protected void onProgressUpdate(Integer... values) {
progressDialog.setMessage("當前下載進度:" + values[0] + "%");
}
@Override//提示任務的執行結果
protected void onPostExecute(Boolean result) {
progressDialog.dismiss();
if (result) {
Toast.makeText(context, "下載成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "下載失敗", Toast.LENGTH_SHORT).show();
}
}
}
複製代碼
任務的啓動和中止只須要如下幾行代碼:
// 開始任務
DownloadTask mDownloadTask = new DownloadTask();
mDownloadTask .execute();
// 中止任務
mDownloadTask .cancel(true);
複製代碼
c.工做原理
SerialExecutor.execute()
將FutureTask插入到任務隊列tasks;注意:AsyncTask不適用於進行特別耗時的後臺任務,而是建議用線程池。
推薦閱讀:Android AsyncTask徹底解析,帶你從源碼的角度完全理解、AsyncTask原理及不足
2.HandlerThread
a.HandlerThread是一個線程類,它繼承自Thread
與普通Thread的區別:具備消息循環的效果。原理:
- 內部
HandlerThread.run()
方法中有Looper,經過Looper.prepare()
來建立消息隊列,並經過Looper.loop()
來開啓消息循環。
b實現方法
HandlerThread.start()
開啓線程;HandlerThread.quit()
/quitSafely()
方法來終止線程的執行。private HandlerThread myHandlerThread ;
private Handler handler ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//實例化HandlerThread
myHandlerThread = new HandlerThread("myHandler") ;
//開啓HandlerThread
myHandlerThread.start();
//將Handler對象與HandlerThread線程綁定
handler =new Handler(myHandlerThread.getLooper()){
@Override
publicvoid handleMessage(Message msg) {
super.handleMessage(msg);
// 這裏接收Handler發來的消息,運行在handler_thread線程中
//TODO...
}
};
//在主線程給Handler發送消息
handler.sendEmptyMessage(1) ;
new Thread(new Runnable() {
@Override
publicvoid run() {
//在子線程給Handler發送數據
handler.sendEmptyMessage(2) ;
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
//終止HandlerThread運行
myHandlerThread.quit() ;
}
複製代碼
補充實例:Android 多線程之HandlerThread 徹底詳解
c.用途:
在以前學習Handler機制時知道在子線程使用Handler的方法,其實HandlerThread的出現使得這一過程變得更加簡便,更多解析見淺析HandlerThread
3.IntentService
a.IntentService是一個繼承自Service的抽象類
b.優勢:
c.IntentService內部封裝了HandlerThread和Handler,工做原理:
IntentService.onCreate()
裏建立一個Handle對象即HandlerThread,利用其內部的Looper會實例化一個ServiceHandler對象;ServiceHandler.handleMessage()
中會調用IntentService.onHandleIntent()
,可在該方法中處理後臺任務的邏輯。圖片來源:Android IntentService的使用和源碼分析
d.使用方法:
onHandleIntent()
方法,該方法:
Intent intent = new Intent(this, MyService.class);
intent.putExtra("xxx",xxx);
startService(intent);//啓動服務
複製代碼
注意:無需手動中止服務,
onHandleIntent()
執行結束以後,IntentService會自動中止。
推薦閱讀:Android多線程:IntentService用法&源碼分析
三.線程池
1.優勢
- 線程池的概念來源:Java中的Executor,它是一個接口。
- 線程池的真正實現:ThreadPoolExecutor,提供一系列參數來配置線程池。
//構造參數
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
複製代碼
execute()
方法提交的Runnable對象會存儲在這個參數中。Thread newThread(Runnable r)
。實例:線程池的原理及實現
3.ThreadPoolExecutor的默認工做策略:
4.ThreadPoolExecutor線程池的分類:
推薦閱讀:Java四種線程池的使用
但願這篇文章對你有幫助~