線程池

線程池的優(yōu)點:

  • 重用線程池中的線程夏伊,避免因為線程的創(chuàng)建和銷毀所帶來的性能開銷许师。
  • 能有效控制線程池的最大并發(fā)數屏轰,避免大量的線程之間因相互搶占系統(tǒng)資源而導致的堵塞線程铜靶。
  • 能夠對線程進行簡單的管理叔遂,并提供定時執(zhí)行以及指定間隔循環(huán)執(zhí)行等功能。
    • 相對于AsyncTask來說争剿,最大的優(yōu)勢在于:線程可控已艰!比如在離開了某個頁面,提交到AsyncTask不能的任務不能撤銷秒梅,線程池可以在不需要的時候將某個線程移除旗芬。

ThreadPoolExecutor的介紹

Android中的線程池概念來源于Java中的Executor,Executor是一個接口捆蜀,真正的線程池的實現為ThreadPoolExecutor疮丛。ThreadPoolExecutor提供了一系列參數來配置線程池,通過不同的參數可以創(chuàng)建不同的線程池辆它。

    public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)
  • corePoolSize:核心線程數

默認核心線程會在線程池中一直存活誊薄,即使它們處于閑置狀態(tài)∶誊裕可以通過設置ThreadPoolExecutor的allowCoreThreadTimeOut為true呢蔫,當超過一定的閑置時間,將關閉核心池飒筑,這個時間間隔由keepAliveTime所制定片吊。
  • maximumPoolSize:最大線程數

    當活動線程數達到這個數值后,后續(xù)的新任務將會被阻塞协屡。

  • keepAliveTime:非核心線程時超過時長

    超過這個時長俏脊,非核心池將會被回收。當設置allowCoreThreadTimeOut為true時肤晓,同樣會作用于核心線程爷贫。

  • unit 時間單位

  • workQueue:任務隊列

    通過線程池execute方法提交的Runnable對象會被存儲在這個參數中认然。

  • threadFactory:線程工廠

    為線程池提供創(chuàng)建新線程的功能。 ThreadFactory只是一個接口漫萄,它只有一個方法:Thread new Thread(Runnable r).


典型的線程池配置

  • AsyncTask中的線程池配置:

private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;

private static final ThreadFactory sThreadFactory = new ThreadFactory() {
    private final AtomicInteger mCount = new AtomicInteger(1);

    public Thread newThread(Runnable r) {
        return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
    }
};

private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(10);

/**
 * An {@link Executor} that can be used to execute tasks in parallel.
 */
public static final Executor THREAD_POOL_EXECUTOR
        = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

在不同的android本版本中卷员,AsyncTask的線程池不同,但都大同小異腾务,在另一個版本中的AsyncTask中是使用的CPU核心數為標準來給定核心線程數和最大線程數毕骡。

  • ImageLoad中的線程池:

/** This cache uses a single background thread to evict entries. */
final ThreadPoolExecutor executorService =
        new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

android中提供的一些線程池:

    singleTaskExecutor = Executors.newSingleThreadExecutor();// 每次只執(zhí)行一個線程任務的線程池
    limitedTaskExecutor = Executors.newFixedThreadPool(3);// 限制線程池大小為7的線程池
    allTaskExecutor = Executors.newCachedThreadPool(); // 一個沒有限制最大線程數的線程池
    scheduledTaskExecutor = Executors.newScheduledThreadPool(3);// 一個可以按指定時間可周期性的執(zhí)行的線程池
    scheduledTaskFactoryExecutor = Executors.newFixedThreadPool(3, new ThreadFactoryTest());// 按指定工廠模式來執(zhí)行的線程池
    scheduledTaskFactoryExecutor.submit(new Runnable()
    {

        @Override
        public void run()
        {
            Log.i("KKK", "This is the ThreadFactory Test  submit Run! ! ! ");
        }
    });

線程池的案例:

使用動態(tài)代理方式創(chuàng)建建一個ThreadPoolProxyFactory ,里面提供兩種方式獲取線程池:普通線程池和下載的線程池窑睁。

public class ThreadPoolProxyFactory {
    static ThreadPoolProxy mNormalThreadPoolProxy;
    static ThreadPoolProxy mDownLoadThreadPoolProxy;

    /**
     * 得到普通線程池代理對象mNormalThreadPoolProxy
     */
    public static ThreadPoolProxy getNormalThreadPoolProxy() {
        if (mNormalThreadPoolProxy == null) {
            synchronized (ThreadPoolProxyFactory.class) {
                if (mNormalThreadPoolProxy == null) {
                    mNormalThreadPoolProxy = new ThreadPoolProxy(5, 5);
                }
            }
        }
        return mNormalThreadPoolProxy;
    }

    /**
     * 得到下載線程池代理對象mDownLoadThreadPoolProxy
     */
    public static ThreadPoolProxy getDownLoadThreadPoolProxy() {
        if (mDownLoadThreadPoolProxy == null) {
            synchronized (ThreadPoolProxyFactory.class) {
                if (mDownLoadThreadPoolProxy == null) {
                    mDownLoadThreadPoolProxy = new ThreadPoolProxy(3, 3);
                }
            }
        }
        return mDownLoadThreadPoolProxy;
    }
}

線程池代理,替線程池完成一些操作挺峡。提供了三種方法:執(zhí)行任務,提交任務,移除任務。

public class ThreadPoolProxy {

    ThreadPoolExecutor mExecutor;
    private int mCorePoolSize;
    private int mMaximumPoolSize;


    /**
     * @param corePoolSize    核心池的大小
     * @param maximumPoolSize 最大線程數
     */
    public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
        mCorePoolSize = corePoolSize;
        mMaximumPoolSize = maximumPoolSize;
    }

    /**
     * 初始化ThreadPoolExecutor
     * 雙重檢查加鎖,只有在第一次實例化的時候才啟用同步機制,提高了性能
     */
    private void initThreadPoolExecutor() {
        if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
            synchronized (ThreadPoolProxy.class) {
                if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
                    long keepAliveTime = 3000;
                    TimeUnit unit = TimeUnit.MILLISECONDS;
                    BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>();
                    ThreadFactory threadFactory = Executors.defaultThreadFactory();
                    RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();

                    mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
                            threadFactory, handler);
                }
            }
        }
    }
    /**
     執(zhí)行任務和提交任務的區(qū)別?
     1.有無返回值
        execute->沒有返回值
        submit-->有返回值
     2.Future的具體作用?
        1.有方法可以接收一個任務執(zhí)行完成之后的結果,其實就是get方法,get方法是一個阻塞方法
        2.get方法的簽名拋出了異常===>可以處理任務執(zhí)行過程中可能遇到的異常
     */
    /**
     * 執(zhí)行任務
     */
    public void execute(Runnable task) {
        initThreadPoolExecutor();
        mExecutor.execute(task);
    }

    /**
     * 提交任務
     */
    public Future<?> submit(Runnable task) {
        initThreadPoolExecutor();
        return mExecutor.submit(task);
    }

    /**
     * 移除任務
     */
    public void remove(Runnable task) {
        initThreadPoolExecutor();
        mExecutor.remove(task);
    }
}

具體使用:

  • 普通線程的使用:
ThreadPoolProxyFactory.getNormalThreadPoolProxy().execute(Runnable);
  • 下載線程的使用:
    ThreadPoolProxyFactory.getDownLoadThreadPoolProxy().execute(downLoadTask);
    ThreadPoolProxyFactory.getDownLoadThreadPoolProxy().remove(downLoadInfo.downLoadTask);

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末担钮,一起剝皮案震驚了整個濱河市橱赠,隨后出現的幾起案子,更是在濱河造成了極大的恐慌箫津,老刑警劉巖狭姨,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異苏遥,居然都是意外死亡饼拍,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門田炭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來师抄,“玉大人,你說我怎么就攤上這事教硫∵端保” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵瞬矩,是天一觀的道長茶鉴。 經常有香客問我,道長景用,這世上最難降的妖魔是什么涵叮? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮伞插,結果婚禮上割粮,老公的妹妹穿的比我還像新娘。我一直安慰自己媚污,他們只是感情好穆刻,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杠步,像睡著了一般氢伟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幽歼,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天朵锣,我揣著相機與錄音,去河邊找鬼甸私。 笑死诚些,一個胖子當著我的面吹牛,可吹牛的內容都是我干的皇型。 我是一名探鬼主播诬烹,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弃鸦!你這毒婦竟也來了绞吁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤唬格,失蹤者是張志新(化名)和其女友劉穎家破,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體购岗,經...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡汰聋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了喊积。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烹困。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖乾吻,靈堂內的尸體忽然破棺而出髓梅,到底是詐尸還是另有隱情,我是刑警寧澤溶弟,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布女淑,位于F島的核電站,受9級特大地震影響辜御,放射性物質發(fā)生泄漏鸭你。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一擒权、第九天 我趴在偏房一處隱蔽的房頂上張望袱巨。 院中可真熱鬧,春花似錦碳抄、人聲如沸愉老。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫉入。三九已至焰盗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咒林,已是汗流浹背熬拒。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留垫竞,地道東北人澎粟。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像欢瞪,于是被迫代替她去往敵國和親活烙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容

  • 前段時間遇到這樣一個問題遣鼓,有人問微信朋友圈的上傳圖片的功能怎么做才能讓用戶的等待時間較短啸盏,比如說一下上傳9張圖片,...
    加油碼農閱讀 1,203評論 0 2
  • Android中的線程 線程,在Android中是非常重要的譬正,主線程處理UI界面宫补,子線程處理耗時操作。如果在主線程...
    shenhuniurou閱讀 755評論 0 3
  • 原文鏈接:http://blog.csdn.net/u010687392/article/details/4985...
    xpengb閱讀 1,324評論 0 1
  • 從用途上來說曾我,線程分為主線程和子線程粉怕,主線程主要處理和界面相關的事情,子線程則往往用于執(zhí)行耗時操作抒巢。 除了Thre...
    小柏不是大白閱讀 629評論 0 3
  • 豬牛羊動物技術咨詢電話:17789763264蛉谜,彭璟(微信同號) 現在羊業(yè)的養(yǎng)殖越來越規(guī)范稚晚,針對于集約化發(fā)展規(guī)劃,...
    彭璟閱讀 686評論 0 1