1、線程概念
- 進程:系統(tǒng)進行資源分配和調(diào)用的獨立單位。每一個進程都有它自己的內(nèi)存空間和系統(tǒng)資源(cpu、內(nèi)存等)。
- 線程:進程中的一段代碼,一個進程中可以有多段代碼。本身不擁有資源(共享所在進程的資源)
- 在同一個進程內(nèi)又可以執(zhí)行多個任務,而每一個任務我們就可以看成是一個線程。
- 是程序的執(zhí)行單元,執(zhí)行路徑。是程序使用CPU的最基本的單位。
- 如果程序只有一條執(zhí)行路徑,那么該程序就是單線程程序。
- 如果程序有多條執(zhí)行路徑,那么該程序就是多線程程序。
2、多線程意義
- 多線程的存在,不是提高程序的執(zhí)行速度。其實是為了提高應用程序的使用率。
- 程序的執(zhí)行其實都是在搶CPU的資源,CPU的執(zhí)行權(quán)。
- 多個進程是在搶這個資源,而其中的某一個進程如果執(zhí)行路徑比較多,就會有更高的幾率搶到CPU的執(zhí)行權(quán)。
- 我們是不敢保證哪一個線程能夠在哪個時刻搶到,所以線程的執(zhí)行有隨機性。
3、并行和并發(fā)
- 并行是邏輯上同時發(fā)生,指在某一個時間內(nèi)同時運行多個程序。
- 并發(fā)是物理上同時發(fā)生,指在某一個時間點同時運行多個程序
4、Java運行原理
java命令會啟動java虛擬機,啟動JVM,等于啟動了一個應用程序,也就是啟動了一個進程。該進程會自動啟動一個“主線程”,然后主線程去調(diào)用某個類的main方法。所以main方法運行在主線程中。在此之前的所有程序都是單線程。
** jvm虛擬機至少啟動了垃圾回收線程和主線程(調(diào)用main方法),所以是多線程的垃圾回收是以防出現(xiàn)內(nèi)存溢出。**
C/C++可以去調(diào)用系統(tǒng)功能并創(chuàng)建進程,然后由Java去調(diào)用,實現(xiàn)多線程程序(Java不可以直接調(diào)用系統(tǒng)功能)
5、線程生命周期
-
基本狀態(tài)圖
20011044-cffc02c7b77b49dfaf42ed611c8b1cf8.png
圖中是線程運行的基本狀態(tài):線程調(diào)用start()方法開始后,就進入到可運行狀態(tài),隨著CPU的資源調(diào)度在運行和可運行之間切換;遇到阻塞則進入阻塞狀態(tài)。
-
加入同步的線程狀態(tài)圖
20012411-7f68664925844134a8a416b63f808fe4.png
當資源被一個線程訪問時,上鎖,其他線程就進入了一個鎖池(Lock pool);
當鎖被釋放,其他線程獲得了鎖,就變?yōu)榭蛇\行狀態(tài)。 -
加入線程間的相互作用
20012759-f5110611bb224169a3eee61e2ffa77e0.png
- 線程間的相互作用:
- 主要是wait和notify方法的介紹。
- 具有wait()和notify()的線程狀態(tài)圖:
- 線程調(diào)用了wait()方法之后,釋放掉鎖,進入等待池(Wait pool) ;收到通知之后等待獲取鎖,獲取鎖之后才可以運行。
- 綜上所述:(線程被阻塞可能是由于下面五方面的原因):
- 調(diào)用sleep(毫秒數(shù)),使線程進入睡眠狀態(tài)。在規(guī)定時間內(nèi),這個線程是不會運行的。
- 用suspend()暫停了線程的執(zhí)行。除非收到resume()消息,否則不會返回“可運行”狀態(tài)。
- 用wait()暫停了線程的執(zhí)行。除非線程收到notify()或notifyAll()消息,否則不會變成“可運行”狀態(tài)。
- 線程正在等候一些IO操作完成。
- 線程試圖調(diào)用另一個對象的“同步”方法,但那個對象處于鎖定狀態(tài),暫時無法使用。
6、線程調(diào)度(兩種)以及設置線程優(yōu)先級:
- 分時調(diào)度模型。所有線程輪流使用CPU的使用權(quán),平均分配每個線程占用CPU的時間片
- 搶占式調(diào)度模型。優(yōu)先讓優(yōu)先級高的線程使用CPU,若相同,則隨機選擇,優(yōu)先級高的線程獲取CPU的時間片相對多一些。Java使用的是搶占式調(diào)度模型。
設置線程優(yōu)先級:
public final int getPriority(); //返回線程對象的優(yōu)先級。默認優(yōu)先級是5。
public final void setPriority(); //設置線程的優(yōu)先級。
MAX_PRIORITY最大優(yōu)先級值是10
MIN_PRIORITY最小優(yōu)先級是1
NORM_PRIORITY默認優(yōu)先級是5
7、 線程控制
父類(Thread)方法:
- a. 線程休眠
public static void sleep(long millis);
//指定毫秒內(nèi)休眠
//自定義類中run()里調(diào)用 Thread.sleep(millis);
// 進入阻塞狀態(tài),但是不釋放資源,容易造成死鎖
b.線程加入
public final void join();
//等待該線程終止,其他線程再開始
//主類中調(diào)用
c.線程禮讓
public static void yield();
//暫停當前正在執(zhí)行的線程對象,并執(zhí)行其他線程
//自定義類中調(diào)用
//讓多個線程的執(zhí)行更和諧,但不能保證一個線程一次。
//釋放資源(CPU、內(nèi)存等),線程重新進入【就緒】狀態(tài),讓相同優(yōu)先級或者高優(yōu)先級線程執(zhí)行
d.后臺線程
public final void setDaemon(boolean on);
//將該線程標記為守護線程或用戶線程,當正在運行的線程都是守護線程時(即主線程滅亡,守護線程隨之消失),Java虛擬機退出
//該方法必須在啟動線程前調(diào)用
//主類中調(diào)用
e.中斷線程
public final void stop();
//該方法已過時,但還可以使用。不建議使用,顯示stop();
//多長時間線程沒有進行就結(jié)束了
//主類中調(diào)用
public void interrupt();
//把線程的狀態(tài)終止,拋出異常InterruptedException


