基礎開始認識 Threading
一個應用程式或行程(Process)可以向作業系統取得多個執行緒(threads),多個執行緒可以模擬出平行處理的效果。一個具備單一(此處的CPU僅考慮單核心)的系統,事實上同一時間只能執行一件事,但如果將一個 CPU 的執行時間切割為很小的單位,將這些單位分給多個行程去使用,就可以模擬出多工(multi-task)的效果,如下圖。
一個可以執行的 Java 類別,在 main 這個特別的方法被執行時,也就擁有了作業系統的一個執行緒,由 main 方法的開始到結束,都使用這個單一執行緒。因此,假如我想設計一個賽馬的程式,就只能讓一匹馬從起點跑到終點,如果想要設計出多匹馬一起跑,而且各自跑到終點,那就要使用多執行緒的功能。
Java 語言中,java.lang.Thread 類別就是設計讓使用者向作業系統取得額外的執行緒,並在這個執行緒類別中,放入設計師想要做的工作,開發人員只需要繼承 Thread 類別即可讓新類別具備執行緒的能力。另外,若我們設計的類別已經繼承了某類別時,因 Java 語言單一繼承的限制性,而無法繼承 Thread 類別時,則可以利用 java.lang.Runnable 這個介面達到多執行緒的目的,本系列文章後續將說明如何利用 Thread 類別與 Runnable 介面來設計多執行緒的程式。
為了要展示執行緒的效果,有時會在程式碼中使用大量的迴圈讓它不要執行慢一點,好看得出它的效用。當然,在練習時可以這麼做,但這只會在執行時增加不必要的 CPU 負荷。若要有停頓效果,應使用讓執行緒暫停的方法,如 sleep(50) 可讓執行緒進入休眠 50 毫秒,刻意使執行速度放慢,才能看出其差異。
執行緒
一個程式在執行過程中可以擁多個執行緒,這些執行緒可以由開發人員決定而擁有不同層級的優先權(priority),而且,每個執行緒都有四種狀態:
- 執行中(Running)
- 執行緒正在執行當中。
- 暫停(Suspended)
- 暫停已在執行當中的執行緒,但可以讓它繼續執行(resume)。
- 被阻擋(Blocked)
- 執行緒因某個特定的資源被其他執行緒占用時,會進入等待的狀態。
- 終止(Terminated)
- 執行緒被終止或停止,但無法再繼續執行。
java.lang.Thread 類別的方法
可以利用繼承 Thread 類別或實作 Runnable 介面來產生執行緒,Thread 類別設計了許多管理執行緒的方法,常用的方法有:
- String getName()
- 取得執行緒的名稱
- void run()
- 執行緒的主要工作內容
- void start()
- 啟動執行緒的方法
- int getPriority()
- 取得執行緒的優先權值
- boolean isAlive()
- 執行緒是否存活著?
- void join()
- 等待執行緒結束,進入終止狀態
- void sleep(long millis)
- 使執行緒進入睡眠狀態,傳入值為睡眠時間,單位是毫秒
main 方法也是個執行緒
每個 Java 應用程式都擁有一個執行緒,因為 main 方法執行時,一定會產生一個執行緒(main thread),讀者可以在 main 方法區塊中,利用 Thread 類別的方法 currentThread() 便可得到目前的執行緒物件,如下程式範例,可取得執行緒的名稱(getName()),或改變該執行緒的名稱(setName()方法)。
執行結果:
兩匹馬假賽跑
若只有使用 main 方法來設計賽馬的程式,不能達到實際的需求,以下的程式利用 for 迴圈讓兩匹馬(整數 h1 與 h2)從 0 加到 5000,看那匹馬先到終點(5000):
執行結果,每一次執行一定是 h1 先到達終點:
每次執行結果都一樣是不符合實際需求的,因此,我們應該把 h2 的工作(從 0 加到 5000)「搬到」另一個執行緒去處理,讓 main 執行緒與新執行緒一起執行,要達到這個功能,我們需要的是 Thread 類別。
如何使用 java.lang.Thread 類別來產生第二個執行緒呢? 下一篇將從【繼承Thread類別】開始實作一個賽馬程式。
版權聲明
本文章授權範圍僅限綠豆湯網站使用,除 Facebook之類社群等未更改本文章出處之分享行為不在此限,其他個人或公司未經作者同意,不得任意將本文章內容轉載至其他網站,或以任何形式重製,為以免觸犯著作權法,請尊重作者之智慧財產權。