欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

分析Android中線程和線程池

 更新時間:2021年06月08日 09:17:18   作者:handsome黃  
我們知道線程是CPU調度的最小單位。在Android中主線程是不能夠做耗時操作的,子線程是不能夠更新UI的。在Android中,除了Thread外,扮演線程的角色有很多,如AsyncTask,IntentService和HandlerThread等等。本文將介紹Android中線程和線程池。

前言

由于內容過多,所以將分為上下兩部分,第一部分主要和大家談談Android中的線程,以及在Android中的常用的線程池。第二部分我們一起來了解一下AsyncTask的使用和工作原理。

HandlerThread

HandlerThread是Thread的子類,它是一種可以使用Handler的Thread,它的實現(xiàn)比較簡單。我們來看看它的源碼:

package android.os;

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }


      public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }


       protected void onLooperPrepared() {
    }



    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }



     public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }

        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }



       public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }





      public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }




     public int getThreadId() {
        return mTid;
    }
}

為了讓大家看清楚,我們源碼的一些英文注釋干掉了,現(xiàn)在就很清晰了。整個類中,除了構造方法和對外提供幾個public方法以外,就剩一個方法了run()。從它的實現(xiàn)來看,和普通的Thread實現(xiàn)沒有什么區(qū)別。都是在run()方法中執(zhí)行耗時操作。不過,HandlerThread內部創(chuàng)建了消息隊列,并且run()方法是一個無限循環(huán)的方法,當我們不需要HandlerThread的時候,我們可以調用quitSafely()或者quit()方法來結束這個線程。這是比較方便的。

IntentService

IntentService是一種特殊的Service,它是Service的子類,并且它是一個抽象類,所以必須創(chuàng)建它的子類才可以使用Intent Service。Intent Service可用于執(zhí)行后臺的耗時任務,當任務執(zhí)行完畢,它會自己結束,不需要開發(fā)著手動結束它。這里需要注意一個問題,Intentservice內置有線程,但是它還是屬于Service,所以它的優(yōu)先級會比線程高很多,所以不容易被系統(tǒng)殺死。所以比較合適去執(zhí)行一些優(yōu)先級比較高的任務??纯此脑创a:

package android.app;

import android.annotation.WorkerThread;
import android.annotation.Nullable;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;



public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;



    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }



        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }




    public IntentService(String name) {
        super();
        mName = name;
    }




   public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }




    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }




      @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }




    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }




    public IBinder onBind(Intent intent) {
        return null;
    }




    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

這里就很簡單了,這些方法對于經常使用Service的朋友來說,就很熟悉了。大家看onCreate()方法。沒錯IntentService就是封裝了HandlerThread和Handler。

當我們啟動IntentService是onCreate(),方法將會被調用,然后就會創(chuàng)建HandlerThread和ServiceHandler。而onStartCommand()方法又調用了onStart()方法,從onStart()方法可以看出IntentService 僅僅是通過ServiceHandler來發(fā)一個消息,這個消息會在HandlerThread中被處理掉。

大家看這個onStart()方法,將intent作為消息傳遞給onHandleIntent,這個intent通常是我們傳遞進來的數據。而onHandleIntent就是通過這個intent來區(qū)別具體的后臺任務的。

好了,AsyncTask的使用和工作原理。我們會在下一章在說。下面我們看看線程池吧。

不知道大家有沒有遇到過這種情況。我們在寫項目,遇到耗時操作的時候,怎么辦呢,是不是new Thread().start,那這樣的話,整個項目中得new多少個Thread。這種明顯是很浪費性能。畢竟線程也是好資源的嘛。那么有沒有一種可以方法對線程進行復用呢?答案就是線程池。

線程池的好處

1、重用線程池中的線程,避免因為線程的創(chuàng)建和銷毀帶來的性能開銷。

2、能有效的控制線程池中的線程并發(fā)數,避免大量線程之間因為互相搶占資源而導致的阻塞現(xiàn)象。

3、能夠對線程進行簡單的管理,并提供定時執(zhí)行以及指定間隔循環(huán)執(zhí)行等功能。

ThreadPoolExecutor

Android中的線程池概念是來源于java中Executor,Executor是一個空的接口,真正的線程池實現(xiàn)ThreadPoolExecutor。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

簡單介紹一下ThreadPoolExcutor各個參數的含義

corePoolSize:線程池的核心線程數,默認情況下,核心線程會在線程池中一直存活,即使他們處于閑置狀態(tài)。當我們把ThreadPoolExecutor中的allowCoreThreadTimeOut屬性設置為true,那么閑置的核心線程在等待新任務的時候,如果時間超過keepAliveTime所設置的時間,核心線程將會被回收。

maximumPoolSize:設置最大線程池能夠容納的最大線程數,當線程池中的線程達到這個數以后,新任務將會被阻塞。

keepAliveTime:非核心線程數閑置的時間。

unit:指定keepAliveTime參數的時間單位。

workQueue:線程池中的任務隊列。

threadFactory:線程工廠,為線程池提供創(chuàng)建新線程的功能。

線程池的分類

Android中常見的線程池有四種,F(xiàn)ixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor。

FixedThreadPool

FixedThreadPool線程池是通過Executors的new FixedThreadPool方法來創(chuàng)建。它的特點是該線程池中的線程數量是固定的。即使線程處于閑置的狀態(tài),它們也不會被回收,除非線程池被關閉。當所有的線程都處于活躍狀態(tài)的時候,新任務就處于隊列中等待線程來處理。注意,F(xiàn)ixedThreadPool只有核心線程,沒有非核心線程。

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                            0L, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                            threadFactory);
}

CachedThreadPool

CachedThreadPool線程池是通過Executors的newCachedThreadPool進行創(chuàng)建的。它是一種線程數目不固定的線程池,它沒有核心線程,只有非核心線程,當線程池中的線程都處于活躍狀態(tài),就會創(chuàng)建新的線程來處理新的任務。否則就會利用閑置的線程來處理新的任務。線程池中的線程都有超時機制,這個超時機制時長是60s,超過這個時間,閑置的線程就會被回收。這種線程池適合處理大量并且耗時較少的任務。這里得說一下,CachedThreadPool的任務隊列,基本都是空的。

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                60L, TimeUnit.SECONDS,
                                new SynchronousQueue<Runnable>());
}

ScheduledThreadPool

ScheduledThreadPool線程池是通過Executors的newScheduledThreadPool進行創(chuàng)建的,它的核心線程是固定的,但是非核心線程數是不固定的,并且當非核心線程一處于空閑狀態(tài),就立即被回收。這種線程適合執(zhí)行定時任務和具有固定周期的重復任務。

public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }


public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue(), threadFactory);
    }

SingleThreadExecutor

SingleThreadExecutor線程池是通過Executors的newSingleThreadExecutor方法來創(chuàng)建的,這類線程池中只有一個核心線程,也沒有非核心線程,這就確保了所有任務能夠在同一個線程并且按照順序來執(zhí)行,這樣就不需要考慮線程同步的問題。

public static ExecutorService newSingleThreadExecutor() {

        return new FinalizableDelegatedExecutorService

            (new ThreadPoolExecutor(1, 1,

                                    0L, TimeUnit.MILLISECONDS,

                                    new LinkedBlockingQueue<Runnable>()));

    }

以上就是分析Android中線程和線程池的詳細內容,更多關于Android中線程和線程池的資料請關注腳本之家其它相關文章!

相關文章

  • Android即時通訊設計(騰訊IM接入和WebSocket接入)

    Android即時通訊設計(騰訊IM接入和WebSocket接入)

    本文主要介紹了Android即時通訊設計(騰訊IM接入和WebSocket接入),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • Android UI開發(fā)中所遇到的各種坑

    Android UI開發(fā)中所遇到的各種坑

    今天小編就為大家分享一篇關于Android UI開發(fā)中所遇到的各種坑,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Android App后臺服務報告工作狀態(tài)實例

    Android App后臺服務報告工作狀態(tài)實例

    這篇文章主要介紹了Android App后臺服務報告工作狀態(tài)實例,使用LocalBroadcastManager發(fā)送和接收狀態(tài),需要的朋友可以參考下
    2014-06-06
  • Android webview用法實例簡析

    Android webview用法實例簡析

    這篇文章主要介紹了Android webview用法,結合實例形式簡單分析了Android中webview的功能、用法與相關注意事項,需要的朋友可以參考下
    2016-01-01
  • Activity透明/半透明效果的設置transparent(兩種實現(xiàn)方法)

    Activity透明/半透明效果的設置transparent(兩種實現(xiàn)方法)

    兩種方法實現(xiàn)Activity透明/半透明效果的設置,代碼思路很有調理,感興趣的朋友可以參考下,希望本文可以幫助到你
    2013-02-02
  • Android AS為xutils添加依賴過程圖解

    Android AS為xutils添加依賴過程圖解

    這篇文章主要介紹了Android AS為xutils添加依賴過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • Android仿京東首頁秒殺倒計時

    Android仿京東首頁秒殺倒計時

    這篇文章主要為大家詳細介紹了Android仿京東首頁秒殺倒計時,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Android Tabhost使用方法詳解

    Android Tabhost使用方法詳解

    這篇文章主要為大家詳細介紹了Android Tabhost使用方法,如何利用TabHost 實現(xiàn)tab視圖,感興趣的小伙伴們可以參考一下
    2016-06-06
  • android仿360加速球實現(xiàn)內存釋放

    android仿360加速球實現(xiàn)內存釋放

    本篇文章實現(xiàn)了Android仿360加速球實現(xiàn)內存釋放,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • Android入門之Menu組件的使用教程詳解

    Android入門之Menu組件的使用教程詳解

    這篇文章主要為大家詳細介紹了Android中常用的幾個Menu組件的使用教程,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的可以了解一下
    2022-11-11

最新評論