android-线程池-最顺手的写法
生活随笔
收集整理的這篇文章主要介紹了
android-线程池-最顺手的写法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
引子
關于線程池,在這里寫出幾種最順手的寫法,至于原理以及各種細節。放后面再填;
經過查證,凡是?以前new?Thread()的地方,貌似都可以用線程池來執行,優化內存消耗。
?
代碼
系統提供的4種預設線程池類:
1 Runnable runnable = new Runnable() { 2 @Override 3 public void run() { 4 Log.d("atm", "假裝有執行過程·"); 5 } 6 }; 7 8 //第一類 9 // 全部由核心線程去實現,并不會被回收,沒有超時限制和任務隊列的限制,會創建一個定長線程池, 10 // 可控制線程最大并發數,超出的線程會在隊列中等待 11 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); 12 fixedThreadPool.execute(runnable); 13 14 //第二類 15 //該模式下線程數量不定的線程池,只有非核心線程,最大值為Integer.MAX_VALUE,會創建一個可緩存線程池, 16 // 如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程 17 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); 18 cachedThreadPool.execute(runnable); 19 20 //第三類 21 //該模式下核心線程是固定的,非核心線程沒有限制,非核心線程閑置時會被回收。 22 // 會創建一個定長線程池,執行定時任務和固定周期的任務 23 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4); 24 scheduledThreadPool.schedule(runnable, 2000, TimeUnit.SECONDS);//2000ms后執行。 25 scheduledThreadPool.scheduleAtFixedRate(runnable, 10, 1000, TimeUnit.MILLISECONDS);//延遲10ms后,每隔1000ms執行一次 26 27 //第四類, 28 //該模式下線程池內部只有一個線程,所有的任務都在一個線程中執行,會創建一個單線程化的線程池, 29 // 它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行 30 ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); 31 singleThreadExecutor.execute(runnable);?
不用系統的,而是自己定義各種參數:
1 import android.support.annotation.NonNull; 2 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.Future; 5 import java.util.concurrent.LinkedBlockingDeque; 6 import java.util.concurrent.ThreadFactory; 7 import java.util.concurrent.ThreadPoolExecutor; 8 import java.util.concurrent.TimeUnit; 9 import java.util.concurrent.atomic.AtomicInteger; 10 11 /** 12 */ 13 public class CustomThreadPool { 14 15 private static final int CORE_POOL_SIZE = 3;//核心線程數目 16 private static final int MAX_POOL_SIZE = 20;//最大線程數,除了核心線程就是非核心線程 17 private static final int ALIVE_TIME = 5;//非核心線程允許閑置的最大時長 18 19 private static final CustomThreadPool instance; 20 21 private final ThreadPoolExecutor pool; 22 23 static { 24 instance = new CustomThreadPool(); 25 } 26 27 private CustomThreadPool() { 28 //參數逐個解析 29 /** 30 * @param 核心線程的數目,即使他們是閑置狀態,也不會被回收,除非你設置 allowCoreThreadTimeOut,讓核心線程也有超時時間(不過一般不這么做) 31 * @param 線程池的最大容量,可以容納核心線程和非核心線程 32 * @param 當線程數目大于核心線程數,這個值是被回收的最大閑置時間,超出則會被回收 33 * @param 超時時間的單位(一般用秒,或者毫秒) 34 * @param 等待隊列,當核心線程都在工作,而又有新的任務需要執行,這些任務則會先進入等待隊列(但是如果進不去,或者隊列滿了,就會嘗試用非核心線程) 35 * @param 生成線程的工廠(一般都會自己new 一個類繼承ThreadFactory) 36 * @throws IllegalArgumentException 參數異常 37 * 可能拋出的異常, 38 * 比如,你把核心線程數設置為負數; 39 * 或者超時時間設置為負數 40 * 或者最大線程數是非正數; 41 * 或者最大線程數小于 核心線程數 42 * @throws NullPointerException 43 * 當 工作隊列是空,或者 線程工廠,對象是空,就會報空指針 44 */ 45 pool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(), new MyThreadFactory()); 46 } 47 48 public static CustomThreadPool getInstance() { 49 return instance; 50 } 51 52 /** 53 * 執行,無返回值 54 * 55 * @param r 56 */ 57 public void execute(Runnable r) { 58 pool.execute(r); 59 } 60 61 /** 62 * 提交,有返回值 63 * 64 * @param r 65 * @return 66 */ 67 public Future<String> submit(Runnable r, String s) { 68 return pool.submit(r, s); 69 } 70 71 public Future<String> submit(Callable<String> callable) { 72 return pool.submit(callable); 73 } 74 75 private class MyThreadFactory implements ThreadFactory { 76 77 private final AtomicInteger mCount = new AtomicInteger(1); 78 79 @Override 80 public Thread newThread(@NonNull Runnable r) { 81 Thread thread = new Thread(r, "GWThreadPool-" + mCount.getAndIncrement()); 82 thread.setPriority(Thread.NORM_PRIORITY - 1); 83 thread.setDaemon(false); 84 return thread; 85 } 86 } 87 88 }?
帶返回值的執行,以及不帶返回值的執行;
1 private void test2() { 2 //如果你想執行一個帶返回值的任務,任務執行完成之后,返回結果,用下面的代碼 3 try { 4 Callable<String> callable = new Callable<String>() {// 注意這里不是Runnable,而是Callable, 5 @Override 6 public String call() { 7 return "哈哈哈"; 8 } 9 }; 10 11 //````如果你想執行任務,并且要取執行完成之后的返回值,用submit吧 12 Future<String> s = CustomThreadPool.getInstance().submit(callable);//執行,submit 有返回值 13 //下面有5個API可供調用 14 /** 15 * 嘗試取消任務的執行。這種嘗試將會失敗,當任務已經完成,已經被取消,或者因為某種原因不能被取消。 16 * 如果成功取消,這個任務還沒開始的話,那這個任務將永遠不會執行, 17 * 如果任務已經開始,那就要 mayInterruptIfRunning 參數值將會決定是否要嘗試去終止任務;(true,嘗試終止,false,不去嘗試;至于為什么這里是嘗試,而不是一定終止,參照本段開頭;) 18 * 當這個方法返回,后來的調用isDone將會永遠返回true,也就是說,取消也算做是完成? 19 * 后來的調用isCanceled 將會永遠返回true,如果這個方法返回true的話。 20 * @param mayInterruptIfRunning 是否執行這個任務線程的線程能夠被中斷;true能夠中斷,false,將會繼續執行直到完成; 21 * @return 返回值,false,如果這個任務不能被取消,典型的就是這個任務已經完成了·· 其他情況,返回true; 22 */ 23 s.cancel(true);// 取消任務,參數的意思是:是否允許在執行過程中中斷; 如果true,不管是不是已經開始任務,都讓他終止;false,如果已經開始了,就不終止了; 24 s.isDone();//是否已完成 25 s.isCancelled();// 是否已經被取消 26 27 String result = s.get();// 獲取執行的結果,如果任務尚未執行完成,有可能會阻塞一段時間 28 String result2 = s.get(3, TimeUnit.SECONDS);//最多等待3秒,get的重載方法,因為有可能會阻塞,阻塞的時長不定,所以提供一個重載方法,指定阻塞的最大時間; 29 30 //````如果你只是想執行任務,不想要返回值,那么,用execute 31 Runnable runnable = new Runnable() { 32 @Override 33 public void run() { 34 Log.d("hahaha", "假裝這里有代碼"); 35 } 36 }; 37 CustomThreadPool.getInstance().execute(runnable); 38 39 } catch (InterruptedException e) { 40 e.printStackTrace(); 41 } catch (ExecutionException e) { 42 e.printStackTrace(); 43 } catch (TimeoutException e) { 44 e.printStackTrace(); 45 } 46 }?
轉載于:https://www.cnblogs.com/hankzhouAndroid/p/9505423.html
總結
以上是生活随笔為你收集整理的android-线程池-最顺手的写法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue.js--基础事件定义,获取数据,
- 下一篇: sqlx使用说明