
Java 教程
- Java - 首頁
- Java - 概述
- Java - 歷史
- Java - 特性
- Java 與 C++
- JVM - Java 虛擬機器
- Java - JDK vs JRE vs JVM
- Java - Hello World 程式
- Java - 環境搭建
- Java - 基本語法
- Java - 變數型別
- Java - 資料型別
- Java - 型別轉換
- Java - Unicode 系統
- Java - 基本運算子
- Java - 註釋
- Java - 使用者輸入
- Java - 日期與時間
Java 控制語句
- Java - 迴圈控制
- Java - 決策制定
- Java - If-else
- Java - Switch
- Java - For 迴圈
- Java - For-Each 迴圈
- Java - While 迴圈
- Java - do-while 迴圈
- Java - Break
- Java - Continue
面向物件程式設計
- Java - OOPs 概念
- Java - 物件與類
- Java - 類屬性
- Java - 類方法
- Java - 方法
- Java - 變數作用域
- Java - 構造方法
- Java - 訪問修飾符
- Java - 繼承
- Java - 聚合
- Java - 多型
- Java - 重寫
- Java - 方法過載
- Java - 動態繫結
- Java - 靜態繫結
- Java - 例項初始化塊
- Java - 抽象
- Java - 封裝
- Java - 介面
- Java - 包
- Java - 內部類
- Java - 靜態類
- Java - 匿名類
- Java - 單例類
- Java - 包裝類
- Java - 列舉
- Java - 列舉構造方法
- Java - 列舉字串
Java 內建類
Java 檔案處理
Java 錯誤與異常
- Java - 異常
- Java - try-catch 塊
- Java - try-with-resources
- Java - 多重捕獲塊
- Java - 巢狀 try 塊
- Java - Finally 塊
- Java - throw 異常
- Java - 異常傳播
- Java - 內建異常
- Java - 自定義異常
Java 多執行緒
- Java - 多執行緒
- Java - 執行緒生命週期
- Java - 建立執行緒
- Java - 啟動執行緒
- Java - 執行緒連線
- Java - 執行緒命名
- Java - 執行緒排程器
- Java - 執行緒池
- Java - 主執行緒
- Java - 執行緒優先順序
- Java - 守護執行緒
- Java - 執行緒組
- Java - 關閉鉤子
Java 同步
Java 網路
- Java - 網路
- Java - 套接字程式設計
- Java - URL 處理
- Java - URL 類
- Java - URLConnection 類
- Java - HttpURLConnection 類
- Java - Socket 類
- Java - 泛型
Java 集合
Java 介面
Java 資料結構
Java 集合演算法
高階 Java
- Java - 命令列引數
- Java - Lambda 表示式
- Java - 傳送郵件
- Java - Applet 基礎
- Java - Javadoc 註釋
- Java - 自動裝箱和拆箱
- Java - 檔案不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 檔案
- Java - 私有介面方法
- Java - 內部類菱形運算子
- Java - 多解析度影像 API
- Java - 集合工廠方法
- Java - 模組系統
- Java - Nashorn JavaScript
- Java - Optional 類
- Java - 方法引用
- Java - 函式式介面
- Java - 預設方法
- Java - Base64 編碼解碼
- Java - Switch 表示式
- Java - Teeing 收集器
- Java - 微基準測試
- Java - 文字塊
- Java - 動態 CDS 歸檔
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指標異常
- Java - 打包工具
- Java - 密封類
- Java - 記錄類
- Java - 隱藏類
- Java - 模式匹配
- Java - 簡潔數字格式化
- Java - 垃圾回收
- Java - JIT 編譯器
Java 雜項
- Java - 遞迴
- Java - 正則表示式
- Java - 序列化
- Java - 字串
- Java - 程序 API 改進
- Java - 流 API 改進
- Java - 增強的 @Deprecated 註解
- Java - CompletableFuture API 改進
- Java - 流
- Java - 日期時間 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java API 和框架
Java 類參考
- Java - Scanner
- Java - 陣列
- Java - 字串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用資源
Java - 多執行緒
Java 是一種多執行緒程式語言,這意味著我們可以使用 Java 開發多執行緒程式。多執行緒程式包含兩個或多個可以併發執行的部分,並且每個部分可以同時處理不同的任務,從而充分利用可用資源,尤其是在您的計算機有多個CPU時。
根據定義,多工處理是指多個程序共享 CPU 等公共處理資源。多執行緒將多工處理的概念擴充套件到應用程式中,在應用程式中,您可以將單個應用程式內的特定操作細分為單獨的執行緒。每個執行緒都可以並行執行。作業系統不僅在不同的應用程式之間分配處理時間,而且在應用程式內的每個執行緒之間分配處理時間。
Java 多執行緒
多執行緒使您能夠以一種方式編寫程式碼,在該程式碼中,多個活動可以在同一程式中併發進行。為了實現多執行緒(或編寫多執行緒程式碼),您需要java.lang.Thread 類。
Java 多執行緒中執行緒的生命週期
執行緒在其生命週期中會經歷各個階段。例如,執行緒誕生、啟動、執行,然後死亡。下圖顯示了執行緒的完整生命週期。

以下是生命週期的階段:
新建 - 新執行緒從新建狀態開始其生命週期。它保持在此狀態,直到程式啟動執行緒。它也稱為新生執行緒。
可執行 - 新生執行緒啟動後,執行緒變為可執行狀態。處於此狀態的執行緒被認為正在執行其任務。
等待 - 有時,執行緒在等待另一個執行緒執行任務時會過渡到等待狀態。執行緒僅在另一個執行緒發出訊號讓等待執行緒繼續執行時才返回到可執行狀態。
計時等待 - 可執行執行緒可以在指定的時間間隔內進入計時等待狀態。處於此狀態的執行緒在該時間間隔到期或其等待的事件發生時返回到可執行狀態。
終止(死亡) - 可執行執行緒在完成其任務或以其他方式終止時進入終止狀態。
執行緒優先順序
每個 Java 執行緒都有一個優先順序,它可以幫助作業系統確定執行緒的排程順序。
Java 執行緒優先順序範圍在 MIN_PRIORITY(常量 1)和 MAX_PRIORITY(常量 10)之間。預設情況下,每個執行緒都分配了 NORM_PRIORITY(常量 5)的優先順序。
優先順序較高的執行緒對程式更重要,應在優先順序較低的執行緒之前分配處理器時間。但是,執行緒優先順序不能保證執行緒執行的順序,並且在很大程度上取決於平臺。
透過實現 Runnable 介面建立執行緒
如果您的類旨在作為執行緒執行,那麼您可以透過實現Runnable介面來實現。您需要遵循三個基本步驟:
步驟 1:實現 run() 方法
第一步,您需要實現Runnable介面提供的 run() 方法。此方法為執行緒提供了一個入口點,您將在其中放置完整的業務邏輯。以下是 run() 方法的簡單語法:
public void run( )
步驟 2:例項化 Thread 物件
第二步,您將使用以下建構函式例項化Thread物件:
Thread(Runnable threadObj, String threadName);
其中,threadObj是實現Runnable介面的類的例項,threadName是賦予新執行緒的名稱。
步驟 3:使用 start() 方法呼叫執行緒
建立 Thread 物件後,您可以透過呼叫start()方法啟動它,該方法會執行對 run( ) 方法的呼叫。以下是 start() 方法的簡單語法:
void start();
示例:透過實現 Runnable 介面建立執行緒
這是一個建立新執行緒並開始執行它的示例:
class RunnableDemo implements Runnable { private Thread t; private String threadName; RunnableDemo( String name) { threadName = name; System.out.println("Creating " + threadName ); } public void run() { System.out.println("Running " + threadName ); try { for(int i = 4; i > 0; i--) { System.out.println("Thread: " + threadName + ", " + i); // Let the thread sleep for a while. Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Thread " + threadName + " interrupted."); } System.out.println("Thread " + threadName + " exiting."); } public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class TestThread { public static void main(String args[]) { RunnableDemo R1 = new RunnableDemo( "Thread-1"); R1.start(); RunnableDemo R2 = new RunnableDemo( "Thread-2"); R2.start(); } }
輸出
Creating Thread-1 Starting Thread-1 Creating Thread-2 Starting Thread-2 Running Thread-1 Thread: Thread-1, 4 Running Thread-2 Thread: Thread-2, 4 Thread: Thread-1, 3 Thread: Thread-2, 3 Thread: Thread-1, 2 Thread: Thread-2, 2 Thread: Thread-1, 1 Thread: Thread-2, 1 Thread Thread-1 exiting. Thread Thread-2 exiting.
透過擴充套件 Thread 類建立執行緒
建立執行緒的第二種方法是建立一個擴充套件Thread類的新的類,使用以下兩個簡單的步驟。這種方法在處理使用Thread類中可用方法建立的多個執行緒時提供了更大的靈活性。
步驟 1:重寫 run() 方法
您需要重寫Thread類中可用的run( )方法。此方法為執行緒提供了一個入口點,您將在其中放置完整的業務邏輯。以下是run()方法的簡單語法:
public void run( )
步驟 2:使用 start() 方法呼叫執行緒
建立Thread物件後,您可以透過呼叫start()方法啟動它,該方法會呼叫run( )方法。以下是start()方法的簡單語法:
void start( );
示例:透過擴充套件Thread類建立執行緒
以下是前面程式重寫為擴充套件Thread的示例:
class ThreadDemo extends Thread { private Thread t; private String threadName; ThreadDemo( String name) { threadName = name; System.out.println("Creating " + threadName ); } public void run() { System.out.println("Running " + threadName ); try { for(int i = 4; i > 0; i--) { System.out.println("Thread: " + threadName + ", " + i); // Let the thread sleep for a while. Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Thread " + threadName + " interrupted."); } System.out.println("Thread " + threadName + " exiting."); } public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class TestThread { public static void main(String args[]) { ThreadDemo T1 = new ThreadDemo( "Thread-1"); T1.start(); ThreadDemo T2 = new ThreadDemo( "Thread-2"); T2.start(); } }
輸出
Creating Thread-1 Starting Thread-1 Creating Thread-2 Starting Thread-2 Running Thread-1 Thread: Thread-1, 4 Running Thread-2 Thread: Thread-2, 4 Thread: Thread-1, 3 Thread: Thread-2, 3 Thread: Thread-1, 2 Thread: Thread-2, 2 Thread: Thread-1, 1 Thread: Thread-2, 1 Thread Thread-1 exiting. Thread Thread-2 exiting.
執行緒方法
以下是Thread類中可用的一些重要方法列表。
序號 | 方法及描述 |
---|---|
1 | public void start() 在單獨的執行路徑中啟動執行緒,然後在此Thread物件上呼叫run()方法。 |
2 | public void run() 如果此Thread物件是使用單獨的Runnable目標例項化的,則在此Runnable物件上呼叫run()方法。 |
3 | public final void setName(String name) 更改Thread物件的名稱。還有一個getName()方法用於檢索名稱。 |
4 | public final void setPriority(int priority) 設定此Thread物件的優先順序。可能的值介於1到10之間。 |
5 | public final void setDaemon(boolean on) 值為true表示此執行緒為守護執行緒。 |
6 | public final void join(long millisec) 當前執行緒在此第二個執行緒上呼叫此方法,導致當前執行緒阻塞,直到第二個執行緒終止或指定的毫秒數過去。 |
7 | public void interrupt() 中斷此執行緒,使其繼續執行(如果由於任何原因而被阻塞)。 |
8 | public final boolean isAlive() 如果執行緒處於活動狀態,則返回true,即執行緒啟動後但在執行完成之前。 |
之前的方法是在特定的Thread物件上呼叫的。Thread類中的以下方法是靜態的。呼叫其中一個靜態方法會在當前正在執行的執行緒上執行操作。
序號 | 方法及描述 |
---|---|
1 | public static void yield() 導致當前正在執行的執行緒讓出給任何其他具有相同優先順序且正在等待排程的執行緒。 |
2 | public static void sleep(long millisec) 導致當前正在執行的執行緒至少阻塞指定毫秒數。 |
3 | public static boolean holdsLock(Object x) 如果當前執行緒持有給定Object上的鎖,則返回true。 |
4 | public static Thread currentThread() 返回對當前正在執行的執行緒的引用,該執行緒是呼叫此方法的執行緒。 |
5 | public static void dumpStack() 列印當前正在執行的執行緒的堆疊跟蹤,這在除錯多執行緒應用程式時很有用。 |
示例
以下ThreadClassDemo程式演示了Thread類的一些方法。考慮一個實現Runnable的DisplayMessage類:
// File Name : DisplayMessage.java // Create a thread to implement Runnable public class DisplayMessage implements Runnable { private String message; public DisplayMessage(String message) { this.message = message; } public void run() { while(true) { System.out.println(message); } } }
以下是另一個擴充套件Thread類的類:
// File Name : GuessANumber.java // Create a thread to extentd Thread public class GuessANumber extends Thread { private int number; public GuessANumber(int number) { this.number = number; } public void run() { int counter = 0; int guess = 0; do { guess = (int) (Math.random() * 100 + 1); System.out.println(this.getName() + " guesses " + guess); counter++; } while(guess != number); System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**"); } }
以下是主程式,它使用了上面定義的類:
// File Name : ThreadClassDemo.java public class ThreadClassDemo { public static void main(String [] args) { Runnable hello = new DisplayMessage("Hello"); Thread thread1 = new Thread(hello); thread1.setDaemon(true); thread1.setName("hello"); System.out.println("Starting hello thread..."); thread1.start(); Runnable bye = new DisplayMessage("Goodbye"); Thread thread2 = new Thread(bye); thread2.setPriority(Thread.MIN_PRIORITY); thread2.setDaemon(true); System.out.println("Starting goodbye thread..."); thread2.start(); System.out.println("Starting thread3..."); Thread thread3 = new GuessANumber(27); thread3.start(); try { thread3.join(); } catch (InterruptedException e) { System.out.println("Thread interrupted."); } System.out.println("Starting thread4..."); Thread thread4 = new GuessANumber(75); thread4.start(); System.out.println("main() is ending..."); } } class DisplayMessage implements Runnable { private String message; public DisplayMessage(String message) { this.message = message; } public void run() { while(true) { System.out.println(message); } } } class GuessANumber extends Thread { private int number; public GuessANumber(int number) { this.number = number; } public void run() { int counter = 0; int guess = 0; do { guess = (int) (Math.random() * 100 + 1); System.out.println(this.getName() + " guesses " + guess); counter++; } while(guess != number); System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**"); } }
輸出
Starting hello thread... Starting goodbye thread... Hello Hello Hello Hello Hello Hello Goodbye Goodbye Goodbye Goodbye Goodbye .......
主要的Java多執行緒概念
在Java中進行多執行緒程式設計時,您需要掌握以下概念: