Java線程的CPU時間片

Java中線程會按優先級分配CPU時間片運行,那麼線程何時放棄CPU的使用權?能夠歸類成三種狀況:linux

  1. 當前運行線程主動放棄CPU,JVM暫時放棄CPU操做(基於時間片輪轉調度的JVM操做系統不會讓線程永久放棄CPU,或者說放棄本次時間片的執行權),例如調用yield()方法。windows

  2. 當前運行線程由於某些緣由進入阻塞狀態,例如阻塞在I/O上。bash

  3. 當前運行線程結束,即運行完run()方法裏面的任務。多線程

三種狀況中第三種很好理解,任務執行完了天然放棄CPU,前兩種狀況用兩個例子說明,先看使用yield放棄CPU什麼狀況:併發

public class YeildThread {
 public static void main(String[] args) {
     MyThread mt = new MyThread();
     mt.start();
     while (true) {
         System.out.println("主線程");
     }
 }
}
class MyThread extends Thread {
 public void run() {
     while (true) {
         System.out.println("被放棄線程");
         Thread.currentThread().yield();
     }
 }
}
複製代碼

截取某段輸出以下,輸出「主線程」比「被放棄線程」運行的機會多,由於mt線程每次循環都把時間片讓給主線程,正是由於yield操做並不會永遠放棄CPU,僅僅只是放棄了這次時間片,把剩下的時間讓給別的線程,機器學習

主線程
主線程
主線程
主線程
主線程
主線程
被放棄線程
主線程
主線程
主線程
主線程
主線程
主線程
主線程
複製代碼

第二個例子爲節省代碼量將使用僞代碼表示,例子簡單但已能說明問題,運行程序將有兩條線程工做,ioThread每次遇到I/O阻塞就放棄當前的時間片,而主線程則按JVM分配的時間片正常運行。分佈式

public class IOBlockThread {
 public static void main(String[] args) {
     IOThread ioThread = new IOThread();
     ioThread.start();
     主線程任務執行
 }
}
class IOThread extends Thread {
 public void run() {
     while (true) {
         I/O阻塞
     }
 }
}
複製代碼

Java的線程的調度機制都由JVM實現,假若有若干條線程,你想讓某些線程擁有更長的執行時間,或某些線程分配少點執行時間,這時就涉及「線程優先級」,Java把線程優先級分紅10個級別,線程被建立時若是沒有明確聲明則使用默認優先級,JVM將根據每一個線程的優先級分配執行時間的機率。有三個常量Thread.MIN_PRIORITY、Thread.NORM_PRIORITY、Thread.MAX_PRIORITY分別表示最小優先級值(1)、默認優先級值(5)、最大優先級值(10)。學習

因爲JVM的實現以宿主操做系統爲基礎,因此Java優先級值與各類不一樣操做系統的原生線程優先級必然存在某種映射關係,這樣才足以封裝全部操做系統的優先級提供統一優先級語義。例如1-10優先級值在linux可能要與0-99優先級值進行映射,而windows系統則有7個優先級要映射。spa

線程的調度策略決定上層多線程運行機制,JVM的線程調度器實現了搶佔式調度,每條線程執行的時間由它分配管理,它將按照線程優先級的建議對線程執行的時間進行分配,優先級越高,可能獲得CPU的時間則越長。操作系統

-------------推薦閱讀------------

個人2017文章彙總——機器學習篇

個人2017文章彙總——Java及中間件

個人2017文章彙總——深度學習篇

個人2017文章彙總——JDK源碼篇

個人2017文章彙總——天然語言處理篇

個人2017文章彙總——Java併發篇


跟我交流,向我提問:

這裏寫圖片描述

公衆號的菜單已分爲「分佈式」、「機器學習」、「深度學習」、「NLP」、「Java深度」、「Java併發核心」、「JDK源碼」、「Tomcat內核」等,可能有一款適合你的胃口。

爲何寫《Tomcat內核設計剖析》

歡迎關注:

這裏寫圖片描述
相關文章
相關標籤/搜索