在 JVM 中的執行緒行為

https://www.infoworld.com/article/3336222/java-challengers-6-thread-behavior-in-the-jvm.html

JVM 中的執行緒行為

執行緒指的是同時執行程式流程以提升應用程式效能的做法。雖然直接在商業應用程式中操作執行緒並不常見,但在 Java 框架中總是會遇到。舉例來說,處理大量資訊的框架會使用執行緒來管理資料。同時操作執行緒或 CPU 流程可以提升效能,從而讓程式更快速、更有效率。

本文介紹傳統 Java 執行緒和 Java 虛擬機中的執行緒執行。欲了解虛擬執行緒和 Java 新的結構性併發模型,請參閱 InfoWorld 的 Project Loom 簡介。

尋找你的第一個執行緒:Java 的 main() 方法

即使您沒有直接操作過 Java 執行緒,由於 Java 的 main() 方法包含一個主執行緒,您無疑間接地操作過它。每當執行 main() 方法時,也同時執行主執行緒。

研讀 Thread 類別對於理解 Java 程式中執行緒運作非常有幫助。我們可以透過調用 currentThread().getName() 方法來存取正在執行的執行緒,如下:

public class MainThread {

public static void main(String… mainThread) {
System.out.println(Thread.currentThread().getName());
}

}

這段程式將會印出 “main”,識別目前正在執行的執行緒。認識如何辨識目前正在執行的執行緒是吸收執行緒概念的第一步。

Java 執行緒的生命週期

在操作執行緒時,要注意執行緒狀態至關重要。Java 執行緒的生命週期包括六種執行緒狀態:

New:已實例化新的 Thread()。

Runnable:呼叫了 Thread 的 start() 方法。

Running:已呼叫 start() 方法且執行緒正在運行。

Suspended:執行緒暫時被暫停,可透過其他執行緒恢復。

Blocked:執行緒正在等待機會運行。當一個執行緒已經呼叫 synchronized() 方法,下一個執行緒必須等待它執行完畢。

Terminated:執行緒的執行已完成。

這裡有更多有關執行緒狀態的資訊,但 Figure 1 中的資訊此時就夠了。

擴展 Thread 類別

最簡單的並行處理是透過擴展 Thread 類別完成,如下所示:

public class InheritingThread extends Thread {

InheritingThread(String threadName) {
super(threadName);
}

public static void main(String… inheriting) {
System.out.println(Thread.currentThread().getName() + ” is running”);

new InheritingThread(“inheritingThread”).start();
}

@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ” is running”);
}
}

在這裡,我們執行兩個執行緒:MainThread 和 InheritingThread。當我們對 new inheritingThread() 呼叫 start() 方法時,run() 方法中的邏輯就被執行了。

我們也在 Thread 類別建構子中傳入第二個執行緒的名稱,因此輸出將會是:

main is running.
inheritingThread is running.

Runnable 介面

我們也可以選擇實作 Runnable 介面,而非使用繼承。將 Runnable 傳入 Thread 建構子之後,可以減少耦合並增加靈活性。在傳入 Runnable 後,我們可以像上個範例一樣呼叫 start() 方法:

public class RunnableThread implements Runnable {

public static void main(String… runnableThread) {
System.out.println(Thread.currentThread().getName());

new Thread(new RunnableThread()).start();
}

@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}

}

非後台 vs. 後台執行緒

在執行方面,有兩種執行緒類型:

非後台執行緒會一直執行到結束。主執行緒是非後台執行緒的一個好例子。main() 中的程式碼將會一直執行到結束,除非 System.exit() 強制程序結束。

後台執行緒則相反,基本上是一個不需要執行到結束的程序。

要記住的規則是:如果包含非後台執行緒的執行緒結束得比後台執行緒早,後台執行緒就不會一直執行到結束。

要更好了解後台和非後台執行緒的關係,請研究以下範例:

import java.util.stream.IntStream;

public class NonDaemonAndDaemonThread {

public static void main(String… nonDaemonAndDaemon) throws InterruptedException {
System.out.println(“Starting the execution in the Thread ” + Thread.currentThread().getName());

Thread daemonThread = new Thread(() -> IntStream.rangeClosed(1, 100000).forEach(System.out::println));

daemonThread.setDaemon(true);
daemonThread.start();

Thread.sleep(10);

System.out.println(“End of the execution in the Thread ” + Thread.currentThread().getName());
}

}

via InfoWorld

June 27, 2024 at 05:07PM

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *