91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中的線程池是如何運行的

發布時間:2020-11-30 16:07:15 來源:億速云 閱讀:145 作者:Leah 欄目:開發技術

本篇文章給大家分享的是有關Java中的線程池是如何運行的,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

異步編程工具在Android開發中目前最被推薦的就是Kotlin協程,在引入Kotlin協程機制前,除了響應式擴展(RxJava)兼任異步編程工具外,Java API中線程與線程池就是最重要異步編程手段。而對于Android平臺的Kotlin協程實現來說,依然使用的是線程池來作為任務執行的載體,所以可以將Android平臺的Kotlin協程簡單的理解是對線程池的一種高度封裝。

Executors.newFixedThreadPool(10).asCoroutineDispatcher()
Dispatchers.IO.asExecutor()

因此我們先了解Java線程池是如何運行的,再深入理解Kotlin協程是如何實現的。

從Thread到Executor

線程的創建通過Thread類,為了復用線程而進行池化就有了線程池。線程池帶來了兩點明顯優勢:

  • 降低重復創建線程的開銷

  • 將任務與線程管理解耦

Executor接口就是第二點的體現。其execute方法用于執行任務,不必關系這個任務執行的載體究竟是什么,到底有沒有創建線程。ThreadPoolExecutor實現類就是這個任務執行器的線程池實現。

ThreadPoolExecutor的任務添加與線程復用

 public void execute(Runnable command) {
  if (command == null)
   throw new NullPointerException();
  int c = ctl.get();
  if (workerCountOf(c) < corePoolSize) {
   if (addWorker(command, true))
    return;
   c = ctl.get();
  }//1
  if (isRunning(c) && workQueue.offer(command)) {
   int recheck = ctl.get();
   if (! isRunning(recheck) && remove(command))
    reject(command);
   else if (workerCountOf(recheck) == 0)
    addWorker(null, false);
  }//2
  else if (!addWorker(command, false))
   reject(command);//3
 }

查看execute方法可以清楚了解其運行方式:

  1. 當線程數小于corePoolSize時,創建線程并執行任務;

  2. 若任務未通過步驟1添加,則入隊workQueue;(主要邏輯在if的條件判斷中,而if內的邏輯處理的是在一些異常下,對入隊的回滾或補充創建線程)

  3. 若任務未入隊,則仍創建線程(上限為maximumPoolSize)并執行任務,失敗則執行拒絕策略。

boolean addWorker(Runnable firstTask, boolean core)就是創建線程的方法,方法中第二個參數代表以corePoolSize還是maximumPoolSize為界,方法內其余創建線程的細節邏輯不深究。但要關注一下線程的封裝類Worker,addWorker方法內調用了Worker內被封裝線程的start方法,執行Worker的run方法。我們將run方法內的runWorker簡化如下:

 void runWorker(Worker w) {
  Runnable task = w.firstTask;
  w.firstTask = null;
  while (task != null || (task = getTask()) != null) {
   task.run();
  }
 }

可以發現,初始任務執行完后,不斷通過getTask方法獲取任務執行,以此來實現線程的復用,而不是只執行完一個任務就銷毀了線程。

另外查看簡化后的getTask方法如下:

 private Runnable getTask() {
  boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
  try {
   Runnable r = timed ?
     workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
     workQueue.take();
   if (r != null)
    return r;
  } catch (InterruptedException retry) { }
 }

任務是從阻塞隊列workQueue中取出的,并且根據配置allowCoreThreadTimeOut與線程個數是否大于corePoolSize,來決定使用BlockingQueue<Runable>的帶超時時間的取任務方法poll,還是阻塞取任務方法take,以實現任務列表為空時適時銷毀線程還是阻塞線程。

回過頭來看ThreadPoolExecutor的構造方法:

 public ThreadPoolExecutor(int corePoolSize,
        int maximumPoolSize,
        long keepAliveTime,
        TimeUnit unit,
        BlockingQueue<Runnable> workQueue,
        ThreadFactory threadFactory,
        RejectedExecutionHandler handler)

以上就是Java中的線程池是如何運行的,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

天台县| 常山县| 德阳市| 天气| 南安市| 樟树市| 且末县| 巩留县| 宜宾县| 海伦市| 河源市| 固镇县| 旬阳县| 芜湖市| 台前县| 仲巴县| 阿拉善左旗| 昆山市| 铜鼓县| 浠水县| 赫章县| 方城县| 南阳市| 苍南县| 天水市| 塘沽区| 吴忠市| 长宁县| 凌云县| 阜阳市| 呼伦贝尔市| 乌海市| 温宿县| 蕉岭县| 枝江市| 孝义市| 修武县| 龙泉市| 凤山市| 马鞍山市| 尼玛县|