Android中使用線程池來管理線程

背景:每出現一個耗時操作都去創建一個新的線程必然不優美,既沒有高併發,對資源的共享和競爭也是比較混亂。總之:
a. 每次new Thread新建對象性能差。
b. 線程缺乏統一管理,可能無限制新建線程,相互之間競爭,及可能佔用過多系統資源導致死機或oom。
c. 缺乏更多功能,如定時執行、定期執行、線程中斷。
相比new Thread,Java提供的四種線程池的好處在於:
a. 重用存在的線程,減少對象創建、消亡的開銷,性能佳。
b. 可有效控制最大併發線程數,提高系統資源的使用率,同時避免過多資源競爭,避免堵塞。
c. 提供定時執行、定期執行、單線程、併發數控制等功能。

一、newCacheThreadPool一個無限大並可以緩存的線程池。在之前創建新線程的時刻首先複用已經創建過的空閒線程。

ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
        for ( int i = 0 ; i<10 ; i++ ){
            final  int index = i;
            try {
                Thread.sleep(index*10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //拿到線程的對象的時候將線程扔到線程池中
            cacheThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d( "newCachedThreadPool" , "" + index );
                }
            });
        }

二、newFixedThreadPool 可以控制最大併發數的線程池。超過最大併發數的線程進入等待隊列。

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i= 0;i<10;i++){
            final  int index = i;
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Log.d("newFixedThreadPool",index+"");
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

三、newScheduledThreadPool 一個可以定時執行的線程池。

延時1s執行

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        scheduledThreadPool.schedule(new Runnable() {
            @Override
            public void run() {
                Log.d("newScheduledThreadPool","延期3秒執行");
            }
        },3, TimeUnit.SECONDS);

延時1s後每隔3s執行一次

public void initImTimeThreadPool(){
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Log.d("newScheduledThreadPool","延時1s後每3s執行一次");
            }
        },1,3,TimeUnit.SECONDS);
    }

四、newSingleThreadExecutor 單線程化線程池。支持FIFO、LIFO的優先級執行。

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i<10 ;i++){
            final int index = i ;
            singleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Log.d("newSingleThreadExecutor",""+index);
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

那麼問題來了,以上都是講創建線程池並且將線程扔到線程池裏面,那麼,對於在線程池中的線程,我們該如何進行管理呢?

execute()方法實際上是Executor中聲明的方法,在ThreadPoolExecutor進行了具體的實現,這個方法是ThreadPoolExecutor的核心方法,

通過這個方法可以向線程池提交一個任務,交由線程池去執行。

submit()方法是在ExecutorService中聲明的方法,在AbstractExecutorService就已經有了具體的實現,

在ThreadPoolExecutor中並沒有對其進行重寫,這個方法也是用來向線程池提交任務的,但是它和execute()方法不同,

它能夠返回任務執行的結果,去看submit()方法的實現,會發現它實際上還是調用的execute()方法,

只不過它利用了Future來獲取任務執行結果(Future相關內容將在下一篇講述)。

shutdown()和shutdownNow()是用來關閉線程池的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章