用程式碼說話:如何在Java中實現執行緒
併發程式設計是Java語言的重要特性之一,“如何在Java中實現執行緒”是學習併發程式設計的入門知識,也是Java工程師面試必備的基礎知識。本文從執行緒說起,然後用程式碼說明如何在Java中實現執行緒。
一、什麼是執行緒?
執行緒是作業系統能夠進行運算排程的最小單位,它被包含在程序之中,是程序中的實際運作單位。程式設計師可以通過它進行多處理器程式設計,也可以使用多執行緒對運算密集型任務提速。如果使用得當,執行緒可以有效地降低程式的開發和運維成本,同時能夠提升程式的效能。
二、執行緒和程序有什麼區別?
執行緒是程序的子集,一個程序可以有很多執行緒。每個程序都有自己的記憶體空間,可執行程式碼和唯一程序識別符號(PID)。
每條執行緒並行執行不同的任務。不同的程序使用不同的記憶體空間(執行緒自己的堆疊),而所有的執行緒共享一片相同的記憶體空間(程序主記憶體)。別把它和棧記憶體搞混,每個執行緒都擁有單獨的棧記憶體用來儲存本地資料。
三、如何在Java中實現執行緒?
“如何在Java中實現執行緒”是學習併發程式設計入門的必備知識,對於這個問題也是眾說紛紜?開啟百度搜索一下,一看便知。在資訊爆炸的時代,我認為像孫悟空一樣有一雙火眼金睛是很必要的,分辨出哪些觀點更加準確,才能少走彎路。
那究竟有幾種方法可以實現執行緒?哪一家的言論更權威,被更多的開發者所認同呢?毋庸置疑,當然是官網文件了。文件地址
如圖中所示:
There are two ways to create a new thread of execution.
One is to declare a class to be a subclass of Thread. ...
The other way to create a thread is to declare a class that implements the Runnable interface. ...
現在可以肯定地說,在Java中實現執行緒有兩種方式, 分別是繼承 Thread 類和實現 Runnable 介面。下面分別用兩種方式實現執行緒。
- 方法一:繼承Thread類。
public class MyThread extends Thread {
public static void main(String[] args) {
new MyThread().start();
}
@Override
public void run() {
System.out.println("用Thread類實現執行緒");
}
}
- 方法二:實現Runnable介面。
public class MyRunnable implements Runnable {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
@Override
public void run() {
System.out.println("用Runnable介面實現執行緒");
}
}
- 深入分析
深入去看Thread類的原始碼,可以看到Thread類實現了Runnable介面。
並且Thread類重寫了run方法, run 方法的程式碼如下:
看過原始碼可以發現,其實兩種方法實現執行緒的本質是一樣的,都是最終呼叫了 start()方法來新建執行緒。這兩個方法的最主要區別在於 run()方法的內容來源:
繼承Thread類: run()方法整體被重寫;
實現Runnable介面:最終呼叫 target.run()。
四、實現 Runnable 介面和繼承 Thread 類哪種方式更好?
Runnable和Thread兩者最大的區別是Thread是類而Runnable是介面,至於用類還是用介面,取決於繼承上的實際需要。Java類是單繼承的,實現多個介面可以實現類似多繼承的操作。
使用繼承 Thread 的方式的話,那麼每次想新建一個任務,只能新建一個獨立的執行緒,而這樣做的損耗會比較大。而如果採用實現Runnable介面的話,Runnable就相當於一個作業,而Thread才是真正的處理執行緒,我們需要的只是定義這個作業,然後將作業交給執行緒去處理,這樣就達到了鬆耦合,也符合面向物件裡面組合的使用。
五、總結
當下次再遇到這樣的面試題的時候,可以這樣硬剛面試官:
Java官方文件說明有兩種方式實現執行緒:繼承Thread和實現Runnable介面。
但是深入原始碼會發現,其實是一種本質方式,只能通過新建Thread類來建立執行緒,但是類裡面的run方法有兩種方式來實現,第一種是重寫run方法,第二種實現Runnable介面的run方法,然後再把該runnable例項傳給Thread類