生活随笔
收集整理的這篇文章主要介紹了
Android线程池详解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
引入線程池的好處
1)提升性能。創(chuàng)建和消耗對象費時費CPU資源
2)防止內(nèi)存過度消耗。控制活動線程的數(shù)量,防止并發(fā)線程過多。
我們來看一下線程池的簡單的構造
[html]?view plaincopy print?
public?ThreadPoolExecutor(int?corePoolSize,????????????????????????????????int?maximumPoolSize,????????????????????????????????long?keepAliveTime,????????????????????????????????TimeUnit?unit,????????????????????????????????BlockingQueue?workQueue,????????????????????????????????ThreadFactory?threadFactory,????????????????????????????????RejectedExecutionHandler?handler)?{...}?? 使用上面的方式創(chuàng)建線程池的話,我們需要配置一堆東西,非常麻煩,所以我們不建議這么使用。而是推薦使用Executors的工廠方法來創(chuàng)建線程池,Executors類是官方提供的一個工廠類,它里面封裝好了眾多功能不一樣的線程池。下面就介紹幾個常用的線程池。
[html]?view plaincopy print?
public?ThreadPoolExecutor(????//核心線程數(shù),除非allowCoreThreadTimeOut被設置為true,否則它閑著也不會死????int?corePoolSize,?????//最大線程數(shù),活動線程數(shù)量超過它,后續(xù)任務就會排隊???????????????????????int?maximumPoolSize,?????//超時時長,作用于非核心線程(allowCoreThreadTimeOut被設置為true時也會同時作用于核心線程),閑置超時便被回收???????????????long?keepAliveTime,??????????????????????????????//枚舉類型,設置keepAliveTime的單位,有TimeUnit.MILLISECONDS(ms)、TimeUnit.?SECONDS(s)等????TimeUnit?unit,????//緩沖任務隊列,線程池的execute方法會將Runnable對象存儲起來????BlockingQueue<Runnable>?workQueue,????//線程工廠接口,只有一個new?Thread(Runnable?r)方法,可為線程池創(chuàng)建新線程????ThreadFactory?threadFactory)?? 1、FixedThreadPool() :
該方法返回一個固定線程數(shù)量的線程池,該線程池中的線程數(shù)量始終不變,即不會再創(chuàng)建新的線程,也不會銷毀已經(jīng)創(chuàng)建好的線程,自始自終都是那幾個固定的線程在工作,所以該線程池可以控制線程的最大并發(fā)數(shù)。
栗子:假如有一個新任務提交時,線程池中如果有空閑的線程則立即使用空閑線程來處理任務,如果沒有,則會把這個新任務存在一個任務隊列中,一旦有線程空閑了,則按FIFO方式處理任務隊列中的任務。
[html]?view plaincopy print?
public?static?ExecutorService?newFixThreadPool(int?nThreads){????????return?new?ThreadPoolExecutor(nThreads,?nThreads,?0L,?TimeUnit.MILLISECONDS,?new?LinkedBlockingQueue<Runnable>());????}????//使用????Executors.newFixThreadPool(5).execute(r);???? 2、CachedThreadPool() :
該方法返回一個可以根據(jù)實際情況調(diào)整線程池中線程的數(shù)量的線程池。即該線程池中的線程數(shù)量不確定,是根據(jù)實際情況動態(tài)調(diào)整的。
栗子:假如該線程池中的所有線程都正在工作,而此時有新任務提交,那么將會創(chuàng)建新的線程去處理該任務,而此時假如之前有一些線程完成了任務,現(xiàn)在又有新任務提交,那么將不會創(chuàng)建新線程去處理,而是復用空閑的線程去處理新任務。那么此時有人有疑問了,那這樣來說該線程池的線程豈不是會越集越多?其實并不會,因為線程池中的線程都有一個“保持活動時間”的參數(shù),通過配置它,如果線程池中的空閑線程的空閑時間超過該“保存活動時間”則立刻停止該線程,而該線程池默認的“保持活動時間”為60s。
[html]?view plaincopy print?
public?static?ExecutorService?newCachedThreadPool(int?nThreads){????????return?new?ThreadPoolExecutor(0,?Integer.MAX_VALUE,?60L,?TimeUnit.?SECONDS,?new?SynchronousQueue<Runnable>());????}????//使用????Executors.newCachedThreadPool().execute(r);???? 3、SingleThreadExecutor() :
該方法返回一個只有一個線程的線程池,即每次只能執(zhí)行一個線程任務,多余的任務會保存到一個任務隊列中,等待這一個線程空閑,當這個線程空閑了再按FIFO方式順序執(zhí)行任務隊列中的任務。
[html]?view plaincopy print?
public?static?ExecutorService?newSingleThreadPool?(int?nThreads){????????return?new?FinalizableDelegatedExecutorService?(?new?ThreadPoolExecutor?(1,?1,?0,?TimeUnit.?MILLISECONDS,?new?LinkedBlockingQueue<Runnable>())?);????}????//使用????Executors.newSingleThreadPool?().execute(r);???
4、ScheduledThreadPool() :
該方法返回一個可以控制線程池內(nèi)線程定時或周期性執(zhí)行某任務的線程池。
[html]?view plaincopy print?
public?static?ScheduledExecutorService?newScheduledThreadPool(int?corePoolSize){????return?new?ScheduledThreadPoolExecutor(corePoolSize);????}????public?ScheduledThreadPoolExecutor(int?corePoolSize){????super(corePoolSize,?Integer.MAX_VALUE,?0,?NANOSECONDS,?new?DelayedQueue?());????}????//使用,延遲1秒執(zhí)行,每隔2秒執(zhí)行一次Runnable?r????Executors.?newScheduledThreadPool?(5).scheduleAtFixedRate(r,?1000,?2000,?TimeUnit.MILLISECONDS);??? 自定義線程池
Android中常用的線程池就上面的四種,其實在Java中還有一種常見的線程池(newSingleThreadScheduledExecutor),其實上面的線程池對于我們開發(fā)已經(jīng)是足夠了,不過有時候上面的仍然不能滿足我們,這時候我們就需要自定義不同功能的線程池。上面我們也說了線程池功能的不同歸根到底還是內(nèi)部的
BlockingQueue實現(xiàn)不同,所以,我們要實現(xiàn)我們自己相要的線程池,就必須從BlockingQueue的實現(xiàn)上做手腳。 那么我們接下來就用PriorityBlockingQueue來實現(xiàn)一個FIFO的線程池。
1)創(chuàng)建一個基于PriorityBlockingQueue的線程池
[html]?view plaincopy print?
ExecutorService?priorityThreadPool?=?new?ThreadPoolExecutor(3,3,0L,TimeUnit.SECONDS,new?PriorityBlockingQueue());?? 2)創(chuàng)建一個實現(xiàn)Runnable接口的類,并向外提供我們實現(xiàn)自定義功能,并實現(xiàn)Comparable接口
[html]?view plaincopy print?
public?abstract?class?PriorityRunnable?implements?Runnable,?Comparable?{??????private?int?priority;?????????public?PriorityRunnable(int?priority)?{??????????if?(priority?0)??????????????throw?new?IllegalArgumentException();??????????this.priority?=?priority;??????}?????????@Override??????public?int?compareTo(PriorityRunnable?another)?{??????????int?my?=?this.getPriority();??????????int?other?=?another.getPriority();??????????return?my?1?:?my?>?other???-1?:?0;??????}?????????@Override??????public?void?run()?{??????????doSth();??????}?????????public?abstract?void?doSth();?????????public?int?getPriority()?{??????????return?priority;??????}??}?? 3)使用PriorityRunnable提交任務
[html]?view plaincopy print?
ExecutorService?priorityThreadPool?=?new?ThreadPoolExecutor(3,?3,?0L,?TimeUnit.SECONDS,?new?PriorityBlockingQueue());??????????for?(int?i?=?1;?i?10;?i++)?{??????????????final?int?priority?=?i;??????????????priorityThreadPool.execute(new?PriorityRunnable(priority)?{??????????????????@Override??????????????????public?void?doSth()?{??????????????????????String?threadName?=?Thread.currentThread().getName();??????????????????????Log.v("zxy",?"線程:"?+?threadName?+?",正在執(zhí)行優(yōu)先級為:"?+?priority?+?"的任務");??????????????????????try?{??????????????????????????Thread.sleep(2000);??????????????????????}?catch?(InterruptedException?e)?{??????????????????????????e.printStackTrace();??????????????????????}??????????????????}??????????????});??????????}?? 歡迎大家加移動技術群(278792776),Android,IOS,RN,后臺全搞定
總結
以上是生活随笔為你收集整理的Android线程池详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。