1. 程式人生 > >線程池 的創建小列子,以及參數的介紹

線程池 的創建小列子,以及參數的介紹

art ble 幫我 適合 proc 判斷 代碼 VM 內存空間

線程池的概念大家應該都很清楚,幫我們重復管理線程,避免創建大量的線程增加開銷。

除了降低開銷以外,線程池也可以提高響應速度,了解點 JVM 的同學可能知道,一個對象的創建大概需要經過以下幾步:

  1. 檢查對應的類是否已經被加載、解析和初始化
  2. 類加載後,為新生對象分配內存
  3. 將分配到的內存空間初始為 0
  4. 對對象進行關鍵信息的設置,比如對象的哈希碼等
  5. 然後執行 init 方法初始化對象

創建一個對象的開銷需要經過這麽多步,也是需要時間的嘛,那可以復用已經創建好的線程的線程池,自然也在提高響應速度上做了貢獻。

public class ThreadPool {

//創建自己的線程池

    //一、.先定義線程池的幾個關鍵屬性值
private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();//核心線程數是cpu數的兩倍 private static final int MAXIMUM_POOL_SIZE = 64;//線程池最大的線程數 private static final long KEEP_ALIVE_TIME = 1; //空閑線程保持存活時間為1秒 //二、.然後根據處理的任務類型選擇不同的阻塞隊列 /* 線程池中使用的隊列是 BlockingQueue 接口,常用的實現有如下幾種: 1. ArrayBlockingQueue:基於數組、有界,按 FIFO(先進先出)原則對元素進行排序 2. LinkedBlockingQueue:基於鏈表,按FIFO (先進先出) 排序元素 吞吐量通常要高於 ArrayBlockingQueue Executors.newFixedThreadPool() 使用了這個隊列 3. SynchronousQueue:不存儲元素的阻塞隊列 每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處於阻塞狀態 吞吐量通常要高於 LinkedBlockingQueue Executors.newCachedThreadPool使用了這個隊列 4.PriorityBlockingQueue:具有優先級的、無限阻塞隊列
*/ private final BlockingQueue<Runnable> mWorkQueue = new LinkedBlockingQueue<>(128); //三、創建自己的ThreadFactory //在其中為每個線程設置個名稱 //獲取本類的類名簡稱Class.getName():以String的形式,返回Class對象的“實體”名稱; //Class.getSimpleName():獲取源代碼中給出的“底層類”簡稱。 private final String TAG = this.getClass().getSimpleName();
private final ThreadFactory DEFAULT_THREAD_FACTORY = new ThreadFactory() { //AtomicInteger提供原子操作來進行Integer的使用,因此十分適合高並發情況下的使用。AtomicInteger是一個提供原子操作的Integer類,通過線程安全的方式操作加減。 private final AtomicInteger mCount = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r,TAG + "#" +mCount.getAndIncrement()); thread.setPriority(Thread.NORM_PRIORITY);//設置線程的優先級別,值越小,級別越高,這種不是絕對的,只是幾率大。 return thread; } }; //四、然後創建線程池 private ThreadPoolExecutor mExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE,//核心線程的數量 MAXIMUM_POOL_SIZE, //最大線程數量 KEEP_ALIVE_TIME,//超出核心線程數量以外的線程空余存活時間 TimeUnit.SECONDS,//存活時間的單位 mWorkQueue,//保存待執行任務的隊列 DEFAULT_THREAD_FACTORY,//創建新線程使用的工廠 new ThreadPoolExecutor.DiscardOldestPolicy() // 當任務無法執行時的處理器 ); private static volatile ThreadPool mInstance = new ThreadPool(); public static ThreadPool getInstance(){ return mInstance; } public void addTask(Runnable runnable){ mExecutor.execute(runnable);//提交任務的方法 還有一個就是 mExecutor.submit(),提交需要返回值的任務,

//submit() 有三種重載,參數可以是 Callable 也可以是 Runnable

//同時它會返回一個 Funture 對象,通過它我們可以判斷任務是否執行成功。

//獲得執行結果調用 Future.get() 方法,這個方法會阻塞當前線程直到任務完成}

//線程池即使不執行任務也會占用一些資源,所以在我們要退出任務時最好關閉線程池。
    //有兩個方法關閉線程池
    // 1.將線程池設置為 STOP,然後嘗試停止所有線程,並返回等待執行任務的列表
    @Deprecated
    public void shutDownNow(){
       mExecutor.shutdownNow();
    }
    //2.將線程池的狀態設置為 SHUTDOWN,然後中斷所有沒有正在執行的線程

    //它們的共同點是:都是通過遍歷線程池中的工作線程,逐個調用 Thread.interrup() 來中斷線程,所以一些無法響應中斷的任務可能永遠無法停止(比如 Runnable)。
    @Deprecated
    public void shutDown(){
       mExecutor.shutdown();
    }


}

想更深了解線程池,請點擊這個鏈接

:https://blog.csdn.net/mine_song/article/details/70948223

線程池 的創建小列子,以及參數的介紹