當前位置:才華齋>計算機>java語言>

java的多執行緒

java語言 閱讀(1.32W)

  認識多工、多程序、單執行緒、多執行緒

java的多執行緒

要認識多執行緒就要從作業系統的原理說起。

以前古老的DOS作業系統(V 6.22)是單任務的,還沒有執行緒的概念,系統在每次只能做一件事情。比如你在copy東西的時候不能rename檔名。為了提高系統的利用效率,採用批處理來批量執行任務。

現在的作業系統都是多工作業系統,每個執行的任務就是作業系統所做的一件事情,比如你在聽歌的同時還在用MSN和好友聊天。聽歌和聊天就是兩個任務,這個兩個任務是“同時”進行的。一個任務一般對應一個程序,也可能包含好幾個程序。比如執行的MSN就對應一個MSN的程序,如果你用的是windows系統,你就可以在工作管理員中看到作業系統正在執行的程序資訊。

一般來說,當執行一個應用程式的時候,就啟動了一個程序,當然有些會啟動多個程序。啟動程序的時候,作業系統會為程序分配資源,其中最主要的資源是記憶體空間,因為程式是在記憶體中執行的。在程序中,有些程式流程塊是可以亂序執行的,並且這個程式碼塊可以同時被多次執行。實際上,這樣的程式碼塊就是執行緒體。執行緒是程序中亂序執行的程式碼流程。當多個執行緒同時執行的時候,這樣的執行模式成為併發執行。

多執行緒的目的是為了最大限度的利用CPU資源。

Java編寫程式都執行在在Java虛擬機器(JVM)中,在JVM的內部,程式的多工是通過執行緒來實現的。每用java命令啟動一個java應用程式,就會啟動一個JVM程序。在同一個JVM程序中,有且只有一個程序,就是它自己。在這個JVM環境中,所有程式程式碼的執行都是以執行緒來執行。

一般常見的Java應用程式都是單執行緒的。比如,用java命令執行一個最簡單的HelloWorld的Java應用程式時,就啟動了一個JVM程序,JVM找到程式程式的入口點main(),然後執行main()方法,這樣就產生了一個執行緒,這個執行緒稱之為主執行緒。當main方法結束後,主執行緒執行完成。JVM程序也隨即退出 。

對於一個程序中的多個執行緒來說,多個執行緒共享程序的記憶體塊,當有新的執行緒產生的時候,作業系統不分配新的記憶體,而是讓新執行緒共享原有的程序塊的記憶體。因此,執行緒間的通訊很容易,速度也很快。不同的程序因為處於不同的記憶體塊,因此程序之間的通訊相對困難。

實際上,操作的系統的多程序實現了多工併發執行,程式的多執行緒實現了程序的併發執行。多工、多程序、多執行緒的前提都是要求作業系統提供多工、多程序、多執行緒的支援。

在Java程式中,JVM負責執行緒的排程。執行緒排程是值按照特定的機制為多個執行緒分配CPU的使用權。

排程的模式有兩種:分時排程和搶佔式排程。分時排程是所有執行緒輪流獲得CPU使用權,並平均分配每個執行緒佔用CPU的時間;搶佔式排程是根據執行緒的優先級別來獲取CPU的使用權。JVM的執行緒排程模式採用了搶佔式模式。

所謂的“併發執行”、“同時”其實都不是真正意義上的“同時”。眾所周知,CPU都有個時鐘頻率,表示每秒中能執行cpu指令的次數。在每個時鐘週期內,CPU實際上只能去執行一條(也有可能多條)指令。作業系統將程序執行緒進行管理,輪流(沒有固定的順序)分配每個程序很短的一段是時間(不一定是均分),然後在每個執行緒內部,程式程式碼自己處理該程序內部執行緒的時間分配,多個執行緒之間相互的切換去執行,這個切換時間也是非常短的。因此多工、多程序、多執行緒都是作業系統給人的一種巨集觀感受,從微觀角度看,程式的執行是非同步執行的。

Java語言的多執行緒需要作業系統的支援。

Java 虛擬機器允許應用程式併發地執行多個執行執行緒。Java語言提供了多執行緒程式設計的擴充套件點,並給出了功能強大的執行緒控制API。

  在Java中,多執行緒的實現有兩種方式:

  擴充套件ad類

  實現able介面

每個執行緒都有一個優先順序,高優先順序執行緒的執行優先於低優先順序執行緒。每個執行緒都可以或不可以標記為一個守護程式。當某個執行緒中執行的程式碼建立一個新 Thread 物件時,該新執行緒的初始優先順序被設定為建立執行緒的優先順序,並且當且僅當建立執行緒是守護執行緒時,新執行緒才是守護程式。

當 Java 虛擬機器啟動時,通常都會有單個非守護執行緒(它通常會呼叫某個指定類的 main 方法)。Java 虛擬機器會繼續執行執行緒,直到下列任一情況出現時為止:

呼叫了 Runtime 類的 exit 方法,並且安全管理器允許退出操作發生。

非守護執行緒的所有執行緒都已停止執行,無論是通過從對 run 方法的呼叫中返回,還是通過丟擲一個傳播到 run 方法之外的異常。

  執行緒的生命週期:

新建狀態:用new語句建立的執行緒物件處於新建狀態,此時它和其它的java物件一樣,僅僅在堆中被分配了記憶體

就緒狀態:當一個執行緒建立了以後,其他的執行緒呼叫了它的start()方法,該執行緒就進入了就緒狀態。處於這個狀態的執行緒位於可執行池中,等待獲得CPU的使用權

執行狀態:處於這個狀態的執行緒佔用CPU,執行程式的程式碼

阻塞狀態:當執行緒處於阻塞狀態時,java虛擬機器不會給執行緒分配CPU,直到執行緒重新進入就緒狀態,它才有機會轉到執行狀態。

  阻塞狀態分為三種情況:

1、 位於物件等待池中的阻塞狀態:當執行緒執行時,如果執行了某個物件的wait()方法,java虛擬機器就回把執行緒放到這個物件的等待池中

2、 位於物件鎖中的阻塞狀態,當執行緒處於執行狀態時,試圖獲得某個物件的同步鎖時,如果該物件的同步鎖已經被其他的執行緒佔用,JVM就會把這個執行緒放到這個物件的'瑣池中。

3、 其它的阻塞狀態:當前執行緒執行了sleep()方法,或者呼叫了其它執行緒的join()方法,或者發出了I/O請求時,就會進入這個狀態中。

  一、建立並執行執行緒

當呼叫start方法後,執行緒開始執行run方法中的程式碼。執行緒進入執行狀態。可以通過Thread類的isAlive方法來判斷執行緒是否處於執行狀態。當執行緒處於執行狀態時,isAlive返回true,當isAlive返回false時,可能執行緒處於等待狀態,也可能處於停止狀態。