有關AsyncTask的一些隨筆筆記
今天在做有關AsyncTask的題目的時候,突發奇想,要是在子執行緒中初始化一個AsyncTask例項,其各個方法是執行在什麼執行緒中的。
下面
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
Log.d("new Thread", "currentThread="+Thread.currentThread());
new MyTask().execute();
}
}).start();
}
private class MyTask extends AsyncTask<Void, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("onPreExecute", "currentThread="+Thread.currentThread());
}
@Override
protected String doInBackground(Void... voids) {
Log.d("doInBackground", "currentThread="+Thread.currentThread());
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(1);
}
return "END";
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.d("onProgressUpdate", "currentThread="+Thread.currentThread());
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("onPostExecute", "currentThread=" + Thread.currentThread());
}
}
}
然後是執行結果:
可以看出,要是是在子執行緒中初始化一個AsyncTask並執行,只有onPreExecute()
方法是線上程中執行的,而doInBackground
與平時沒有區別,是在自己內部維護的執行緒執行,而onProgressUpdate
與onPostExecute
還是在主執行緒中執行。
另外,如果同時執行多個AsyncTask的話,他們預設是序列執行,因為在整個應用程式中的所有AsyncTask例項都會共用同一個SerialExecutor以及THREAD_POOL_EXECUTOR。(在AsyncTask中這兩個都是類變數,用static修飾的)
AsyncTask中有兩個實現了Executor介面的類,一個是SerialExecutor,另一個是THREAD_POOL_EXECUTOR,很多文章中說SerialExecutor也是一個執行緒池,但就個人的觀點而言,這麼說應該是不準確的,因為在這個類裡面並沒建立執行緒,而Executor介面的作用如下:。
(關於這一點,歡迎交流討論。)
執行提交的Runnable任務的物件。這個介面提供了一種將任務提交與每個任務如何執行的機制解耦的方法,包括執行緒使用,排程等細節。
其中SerialExecutor是用來讓所有任務序列取出, 而ThreadPoolExecutor用於執行指定的任務,在最初的 AsyncTask 中只支援序列工作,後在3.0之後加入了executeOnExecutor方法,該方法提供並行了並行操作,一般而言用法為 ,其引數也可以為自定義的執行緒池。
new AsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"...");
SerialExecutor使任務序列執行的,每個任務還是提交到THREAD_POOL_EXECUTOR 執行緒池中來執行,但只能等上一個執行完,才能提交下一個,因此執行緒池中永遠只有一個任務在執行,當然,可能上一個任務執行完會,執行緒空閒時間還沒超出1秒,這樣就不會被移除執行緒池,線上程數量小於corePoolSize時,會再次建立一個執行緒放入執行緒池來執行新的任務,即使有空閒執行緒,但是卻永遠只能有一個執行緒處於工作狀態。並不是說THREAD_POOL_EXECUTOR 不能併發,只是任務沒有併發提交到它。另外,要實現並行,可以用自定義的ThreadPoolExexutor,也可以用原始碼中提供的THREAD_POOL_EXECUTOR,它的coolPoolsize是CPU的數目+1,maximumPoolSize是2*cpu數目+1,keepAlive時間是1秒,阻塞佇列採用BlockingQueue,長度為128
相關文章
- 隨筆-學習程式設計有沒有必要做筆記?如何做筆記?程式設計筆記
- 隨筆記筆記
- 關於c#使用Npoi庫的一些隨筆C#
- 有關golang通道的面試筆記Golang面試筆記
- 隨堂筆記筆記
- 知識盲點 隨筆筆記筆記
- Python學習筆記(隨筆)Python筆記
- 隨記筆記未整理筆記
- nodejs的TCP相關的一些筆記NodeJSTCP筆記
- 【筆記】關於大資料的一些想法筆記大資料
- [筆記]關於調整的一些建議筆記
- 敏捷開發讀書筆記——隨筆敏捷筆記
- 2024/06/22筆記隨筆筆記
- 2024/06/23筆記隨筆筆記
- 2024/06/25筆記隨筆筆記
- 2024/06/26筆記隨筆筆記
- 2024/07/03筆記隨筆筆記
- Bitbucket / Sourcetree 隨手筆記筆記
- 今日隨筆-構建之法讀書筆記筆記
- 筆記:追隨雲原生的Java筆記Java
- 關於Vue和React區別的一些筆記VueReact筆記
- 關於巨集奕培訓的一些小筆記(三)筆記
- 有關PS的論述. -PS模組配置筆記筆記
- vue一些筆記Vue筆記
- Android:隨筆——記錄一些Andriod開發中不常用的庫Android
- 黑馬筆記--C++基礎篇--隨筆筆記C++
- 關於SQL資料庫一些簡單的筆記SQL資料庫筆記
- 關於PC或筆記本的一些安全設定筆記
- ios layoutSubviews呼叫隨手筆記iOSView筆記
- 有感而發,隨筆記錄筆記
- oracle commit隨筆記載OracleMIT筆記
- SpringBoot隨手筆記Spring Boot筆記
- 隨筆
- oracle一些工作筆記Oracle筆記
- 一些老筆記整理筆記
- hive3.0.0的一些筆記Hive筆記
- npm與yarn的一些筆記NPMYarn筆記
- C語言的一些小筆記C語言筆記