大家好啊,我是湯小圓。
今天給大家推薦的是,進程與線程的入門知識,希望對大家有幫助,謝謝。
簡介
首先用術語來講一下,進程是系統進行資源調度和分配的基本單元,線程是進程的最小執行單元;
比如Windows中的任務管理器,就可以看到正在運行的進程,如下所示
PS:這里要注意一點,程序不等於進程
程序是指令的集合,是靜態的;進程是正在執行的程序,是活的
當你雙擊運行程序(.exe文件)時,程序的指令會加載到內存中,此時你就會得到這個程序的進程
好了,術語講完了,接下來開始講人話
知識點
1. 進程和線程的關系是怎么樣的呢?
進程可以看作一個容器,線程就是容器內的最小執行單元;
我們用一個例子來說明,比如有一個宿舍(進程),宿舍里有兩個人(線程),一個廁所(共享資源)
宿舍和人的關系就是進程和線程的關系
一個進程可以包含多個線程。
2. 既然有了進程,為啥還要有線程呢?
-
每個進程都有自己獨立的數據空間,進程之間不共享這些數據資源,通訊不方便;
但是線程不一樣,一個進程內的多個線程共享這個進程的數據資源,通訊方便
-
多進程之間切換開銷大;
但是多線程不會,線程來回切換開銷很小
(這里簡單解釋下,引入一個虛擬空間的概念,多個進程擁有不同的虛擬空間和緩存,但是多個線程共享進程的虛擬空間和緩存,進程切換之后,緩存失效,要重新去尋址虛擬空間,但是線程因為共享空間,緩存還是可以用的,所以比進程快)
3. 多線程都有哪些好處呢?
多線程相互協作,重復利用系統資源,提高系統吞吐率
如果只是單個線程,那么程序在執行比較耗時的操作(比如IO)時,CPU 是處於空閑的狀態,就會造成資源的浪費
但是多線程可以切換到其他線程,繼續執行其他任務,從而充分利用CPU
比如我們在看電影的時候,眼睛在工作,耳朵也在工作,這樣就可以充分利用我們的身體去享受電影;
但是如果眼睛和耳朵要分開工作,那就難受了(腦補一下聲音畫面不同步的場景)
4. 多線程要怎么確保數據安全呢?
有多種方式:
-
局部變量,即單個線程內定義的局部變量只有自己可見,那肯定是安全的
-
只讀對象,即共享的對象是只讀的,那肯定也是安全的
-
線程安全類,即類本身是線程安全的,那么基於這個類的操作肯定也是安全,比如StringBuffer類
-
同步與鎖機制,即用戶自己通過加鎖,來確保數據安全;這個會導致程序變得復雜且容易出現問題
5. 線程的生命周期都有哪些呢?
通過JDK源碼可以看到,線程的生命周期有6個狀態,如下所示
public enum State {
NEW, // 創建了線程,但是啥也沒干
RUNNABLE, // 啟動了線程,處於運行狀態
BLOCKED, // 阻塞了線程,處於阻塞狀態
WAITING, // 等待狀態,沒有時間限制,直到有其他事件通知
TIMED_WAITING, // 等待狀態,有時間限制,時間到了,會返回到運行狀態
TERMINATED; // 終止狀態,線程結束
}
6. 這些狀態之間的關系是咋樣的呢?
可以用一張圖來描述,如下所示,可以看到除了NEW狀態和TERMINATED狀態,其他狀態都是跟RUNNABLE狀態互通的
7. 那么線程的創建 New 有幾種方式呢?
三種
-
(不推薦)繼承Thread類,但是這樣的話不符合LSP原則(里氏替換原則,詳細內容可參考:https://www.jianshu.com/p/cf9f3c7c0df5)
-
(推薦)實現Runnable接口,比第一種靈活,也更加安全
-
(推薦)實現Callable接口,相比於第二種,多了返回值和異常拋出
8. BLOCKED 狀態一般什么情況下會出現呢?
遇到鎖的情況下,如果鎖沒有釋放,那么線程就會阻塞
9. WAITING 和 TIMED_WAITING有啥區別,不都是等待狀態嗎?
WAITING 狀態會無休止的等待下去,直到其他事件通知它,它才會停止等待,進入RUNNABLE狀態(被動)
TIMED_WAITING 狀態會有一個等待最長時間,如果到了等待最長時間,還沒有人通知它,它會自動停止等待,進入RUNNABLE狀態(被動+主動)
總結
上面只是簡單介紹了線程和進程,真正要學的話東西還是很多的
參考書籍:
-
Java並發編程實戰
-
實戰Java高並發程序設計(第二版)
參考鏈接:
后記
最后,感謝大家的觀看,謝謝。