一、Thread調度的概述
import java.util.*;import java.text.*;public class Task implements Runnable { long n; String id; private long fib(long n) { if (n == 0) return 0L; if (n == 1) return 1L; return fib(n - 1) + fib(n - 2); } public Task(long n, String id) { this.n = n; this.id = id; } public void run() { Date d = new Date(); DateFormat df = new SimpleDateFormat("HH:mm:ss:SSS"); long startTime = System.currentTimeMillis(); d.setTime(startTime); System.out.println("Starting task " + id + " at " + df.format(d)); fib(n); long endTime = System.currentTimeMillis(); d.setTime(endTime); System.out.println("Ending task " + id + " at " + df.format(d) + " after " + (endTime - startTime) + " milliseconds"); }}
Runnable的實作類別以便可以用多個Thread來運行多個執行個體。
import javathreads.examples.ch09.*;import javathreads.examples.ch09.*;public class ThreadTest { public static void main(String[] args) { int nThreads = 3; long n = 20; Thread t[] = new Thread[nThreads]; for (int i = 0; i < t. length; i++) { t[i] = new Thread( new Task(n, "Task " + i)); t[i].start(); } for (int i = 0; i < t. length; i++) { try { t[i].join(); } catch (InterruptedException ie) {} } }}
執行結果:
Starting task Task 1 at 07:06:24:443Starting task Task 0 at 07:06:24:443Starting task Task 2 at 07:06:24:443Ending task Task 2 at 07:06:24:446 after 3 millisecondsEnding task Task 0 at 07:06:24:446 after 3 millisecondsEnding task Task 1 at 07:06:24:446 after 3 milliseconds
從以上結果可以看出,線程的執行並不是按照啟動的順序依次執行。
二、以Thread優先順序來調度Java虛擬機器中線程的四種狀態:Initial 一個線程對象從它建立起到該對象的start方法被調用為止這個時間段處於initial狀態。Runnable start方法執行後,處於這種狀態。Blocked 不能運行因為它在等待某個特定的事件發生。Exiting run方法執行完成。
將Thread調用程式想象成Linked list來儲存它所操作的所有Thread的記錄,每個Thread都在描述該Thread狀態的list上上。Java Thread有11種優先順序,所以可以想象14個Linked list(包括出去exiting之外三種狀態各一個)。
每個線程都有一個優先順序,高優先順序線程的執行優先於低優先順序線程。每個線程都可以或不可以標記為一個精靈。當某個線程中啟動並執行代碼建立一個新 Thread 對象時,該新線程的初始優先順序被設定為建立線程的優先順序,並且若且唯若建立線程是守護線程時,新線程才是精靈。
優先順序異常 有兩種情況下虛擬機器會選擇優先順序低的而不是優先順序高的。 優先順序逆轉 優先順序為8的Thread需要取得優先順序為2的Thread鎖持有的鎖,最後會以優先順序等效為3的等級來運行。可以通過優先順序繼承來解決。 複雜的優先順序: Java指定Thread優先順序的計算公式:RealPriority = JavaPriority + SecondsWaitingForCPU
以Thread優先順序來調度:public final void setPriority(int newPriority)
更改線程的優先順序。
首先調用線程的 checkAccess 方法,且不帶任何參數。這可能拋出 SecurityException。
在其他情況下,線程優先順序被設定為指定的 newPriority 和該線程的線程組的最大允許優先順序相比較小的一個。
public final int getPriority()
返回線程的優先順序。
返回:該線程的優先順序。
三、常見Threading的實現Green Thread 這種模式作業系統完全不知道有關Java Thread的任何事情,由虛擬機器來處理所有Thread API細節。 更多資訊詳見:Green threads
Windows 固有的Thread 32位Windows作業系統對於虛擬機器所使用的多個Thread擁有完全的管轄權,且Java Thread與作業系統Thread有一對一的關係。作業系統使用複雜優先順序的計算來決定哪個Thread應該是當前運行中的Thread。
Linux的固有Thread直道JDK 1.3為止,Linx上的虛擬機器都嘗試使用Green Thread模式。JDK 1.3加入對Linux固有Thread的支援。新的Linux核心使用Native Posix Thread Library,提供了其他動作系統所看到的Java Thread 與 Kernel Thread一對一的映射。