繼承Thread類實作多執行緒簡單實體
文章目錄
- 繼承Thread類實作多執行緒簡單實體
- 一、多執行緒的意義
- 二、多執行緒的創建
- 三、代碼
一、多執行緒的意義
1.為什么要使用多執行緒
(a)提高用戶體驗或者避免ANR
在事件待處理碼中需要使用多執行緒,否則會出現ANR(Application is not responding),或者因為回應時間太慢導致用戶體驗很差,
(b)異步
應用中有些情況并不一定需要同步阻塞去等待回傳結果,可以通過多執行緒實作異步,例如你的應用中的某個Activity需要從云端獲取一些圖片,加載圖片比較耗時,這時就需要異步加載,加載完成一個圖片重繪一個,
(c)多任務
多執行緒下載

2.為什么通過多執行緒可以提高用戶體驗,避免ANR
(a)深入了解
Android應用程式的main執行緒,它負責處理UI的繪制,Android系統為了防止應用程式反應較慢導致無法正常運行做了一個處理,一種情況是當用戶輸入事件5秒內無法得到相應,那么系統會彈出ANR對話框,由用戶決定繼續等待還是強制結束應用程式,另一種情況就是BroadcastReciever超過10s沒執行完也會彈出,
即使你的程式中的某個事件回應不超過5分鐘,人眼可辨別的時間是0.1秒,小于0.1秒基礎感覺不出來,超過0.2秒用戶就覺得有點卡了,俗稱“打嗝”現象,用戶體驗會很差,
比如有些應用,它要顯示很多圖片,所以它是異步的,可以在圖片加載成功之前顯示一個默認的圖片,加載成功后重繪一下即可,
(b)事件處理的原則
①所有耗時的操作都放到其他執行緒去處理,
②Android中的Main執行緒的事件處理不能太耗時,否則后續事件無法在5秒內得到回應,就會彈出ANR對話框,
(c)Main執行緒
①Activity的生命周期的方法
②通常on開頭的方法是在Main執行緒中回呼的
③onStart()、onCreate()、onResume()執行時間決定了首頁的打開時間,
④可以使用SplashScreen,用動態的,讓用戶知道你的應用沒死掉,
3.如何實作多執行緒之間的通訊
(a)Handler
(b)AsyncTask
二、多執行緒的創建
1.繼承Thread類實作多執行緒
Thread本質上也是實作了Runnable介面的一個實體,他代表一個執行緒的實體,并且啟動執行緒的唯一方法就是通過Thread類的start()實體方法,
start()方法是一個native方法,他將啟動一個新執行緒,并執行run()方法,通過自己的類直接extend Thread,并復寫run()方法,就可以啟動新執行緒并執行自己的run()方法,
2.實作Runable介面方式實作多執行緒
如果自己的類已經extends另一個類,就無法直接extends Thread,此時必須實作一個Runnable介面,
同時為了啟動MyThread,需要首先實體化一個Thread,并傳入自己的已經實作好Runnable介面的目標物件,
3.實作Runable和實作Thread的區別
(a)一個類只能繼承一個父類,存在局限;一個類可以實作多個介面
(b)在實作Runnable介面的時候呼叫Thread(Runnable target)創建行程時,使用同一個Runnable實體,則建立的多執行緒的實體變數也是共享的,但是通過繼承Thread類是不能用一個實體建立多個執行緒,故而實作Runnable介面適用于資源共享,當然,繼承Thread類也能夠共享變數,能共享Thread類的static變數
(c)Runnable介面和Thread之間的聯系
public class Thread extends Object implements Runnable
可以看出Thread類也是Runnable介面的子類
三、代碼
MainActivity代碼:
package bnuz.it.wjy.hellothread;
import androidx.appcompat.app.AppCompatActivity;
import android.mtp.MtpConstants;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnOnclick(View view){
// testThread();
// testRunnable();
testSale();
}
public void testThread(){
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
mt1.start();
mt2.start();
}
public void testRunnable(){
MyRunnable mr1 = new MyRunnable();
MyRunnable mr2 = new MyRunnable();
Thread t1 = new Thread(mr1);
// Thread t2 = new Thread(mr2);
// 多個Thread物件可以共用一個mr
// 執行緒同步
Thread t2 = new Thread(mr1);
t1.start();
t2.start();
}
public void testSale(){
SaleTicket saleTicket = new SaleTicket();
Thread t1 = new Thread(saleTicket,"A代理");
Thread t2 = new Thread(saleTicket,"B代理");
Thread t3 = new Thread(saleTicket,"C代理");
Thread t4 = new Thread(saleTicket,"D代理");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
布局代碼:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Thread"
android:id="@+id/Thread"
android:onClick="btnOnclick"
/>
</RelativeLayout>
MyThread類
package bnuz.it.wjy.hellothread;
import android.util.Log;
public class MyThread extends Thread{
@Override
public void run() {
Log.d("TAG",Thread.currentThread().getName()+".run()");
}
}
MyRunnable類
package bnuz.it.wjy.hellothread;
import android.util.Log;
public class MyRunnable implements Runnable{
@Override
// 必須是實作run()方法
public void run() {
Log.d("TAG",Thread.currentThread().getName()+".run()");
}
}
SaleTicket類
package bnuz.it.wjy.hellothread;
import android.util.Log;
public class SaleTicket implements Runnable{
private int ticket = 20;
@Override
public void run() {
while (true){
if(ticket > 0){
Log.d("TAG",Thread.currentThread().getName()+"賣出了第"+(20-ticket+1)+"張票");
ticket--;
}
else{
break;
}
}
try {
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/374814.html
標籤:其他
