1、線程概念
- 進(jìn)程:系統(tǒng)進(jìn)行資源分配和調(diào)用的獨(dú)立單位脑蠕。每一個(gè)進(jìn)程都有它自己的內(nèi)存空間和系統(tǒng)資源(cpu酌泰、內(nèi)存等)媒佣。
- 線程:進(jìn)程中的一段代碼,一個(gè)進(jìn)程中可以有多段代碼陵刹。本身不擁有資源(共享所在進(jìn)程的資源)
- 在同一個(gè)進(jìn)程內(nèi)又可以執(zhí)行多個(gè)任務(wù)默伍,而每一個(gè)任務(wù)我們就可以看成是一個(gè)線程。
- 是程序的執(zhí)行單元,執(zhí)行路徑也糊。是程序使用CPU的最基本的單位炼蹦。
- 如果程序只有一條執(zhí)行路徑,那么該程序就是單線程程序显设。
- 如果程序有多條執(zhí)行路徑框弛,那么該程序就是多線程程序。
2捕捂、多線程意義
- 多線程的存在瑟枫,不是提高程序的執(zhí)行速度。其實(shí)是為了提高應(yīng)用程序的使用率指攒。
- 程序的執(zhí)行其實(shí)都是在搶CPU的資源慷妙,CPU的執(zhí)行權(quán)。
- 多個(gè)進(jìn)程是在搶這個(gè)資源允悦,而其中的某一個(gè)進(jìn)程如果執(zhí)行路徑比較多膝擂,就會(huì)有更高的幾率搶到CPU的執(zhí)行權(quán)。
- 我們是不敢保證哪一個(gè)線程能夠在哪個(gè)時(shí)刻搶到隙弛,所以線程的執(zhí)行有隨機(jī)性架馋。
3、并行和并發(fā)
- 并行是邏輯上同時(shí)發(fā)生全闷,指在某一個(gè)時(shí)間內(nèi)同時(shí)運(yùn)行多個(gè)程序叉寂。
- 并發(fā)是物理上同時(shí)發(fā)生,指在某一個(gè)時(shí)間點(diǎn)同時(shí)運(yùn)行多個(gè)程序
4总珠、Java運(yùn)行原理
java命令會(huì)啟動(dòng)java虛擬機(jī)屏鳍,啟動(dòng)JVM,等于啟動(dòng)了一個(gè)應(yīng)用程序局服,也就是啟動(dòng)了一個(gè)進(jìn)程钓瞭。該進(jìn)程會(huì)自動(dòng)啟動(dòng)一個(gè)“主線程”,然后主線程去調(diào)用某個(gè)類的main方法淫奔。所以main方法運(yùn)行在主線程中山涡。在此之前的所有程序都是單線程。
** jvm虛擬機(jī)至少啟動(dòng)了垃圾回收線程和主線程(調(diào)用main方法)唆迁,所以是多線程的垃圾回收是以防出現(xiàn)內(nèi)存溢出佳鳖。**
C/C++可以去調(diào)用系統(tǒng)功能并創(chuàng)建進(jìn)程,然后由Java去調(diào)用媒惕,實(shí)現(xiàn)多線程程序(Java不可以直接調(diào)用系統(tǒng)功能)
5系吩、線程生命周期
-
基本狀態(tài)圖
圖中是線程運(yùn)行的基本狀態(tài):線程調(diào)用start()方法開始后,就進(jìn)入到可運(yùn)行狀態(tài)妒蔚,隨著CPU的資源調(diào)度在運(yùn)行和可運(yùn)行之間切換穿挨;遇到阻塞則進(jìn)入阻塞狀態(tài)月弛。
-
加入同步的線程狀態(tài)圖
當(dāng)資源被一個(gè)線程訪問時(shí),上鎖科盛,其他線程就進(jìn)入了一個(gè)鎖池(Lock pool)帽衙;
當(dāng)鎖被釋放,其他線程獲得了鎖贞绵,就變?yōu)榭蛇\(yùn)行狀態(tài)厉萝。 -
加入線程間的相互作用
- 線程間的相互作用:
- 主要是wait和notify方法的介紹。
- 具有wait()和notify()的線程狀態(tài)圖:
- 線程調(diào)用了wait()方法之后榨崩,釋放掉鎖谴垫,進(jìn)入等待池(Wait pool) ;收到通知之后等待獲取鎖母蛛,獲取鎖之后才可以運(yùn)行翩剪。
- 綜上所述:(線程被阻塞可能是由于下面五方面的原因):
- 調(diào)用sleep(毫秒數(shù)),使線程進(jìn)入睡眠狀態(tài)彩郊。在規(guī)定時(shí)間內(nèi)前弯,這個(gè)線程是不會(huì)運(yùn)行的。
- 用suspend()暫停了線程的執(zhí)行秫逝。除非收到resume()消息恕出,否則不會(huì)返回“可運(yùn)行”狀態(tài)。
- 用wait()暫停了線程的執(zhí)行违帆。除非線程收到notify()或notifyAll()消息浙巫,否則不會(huì)變成“可運(yùn)行”狀態(tài)。
- 線程正在等候一些IO操作完成前方。
- 線程試圖調(diào)用另一個(gè)對象的“同步”方法,但那個(gè)對象處于鎖定狀態(tài)廉油,暫時(shí)無法使用惠险。
6、線程調(diào)度(兩種)以及設(shè)置線程優(yōu)先級(jí):
- 分時(shí)調(diào)度模型抒线。所有線程輪流使用CPU的使用權(quán)班巩,平均分配每個(gè)線程占用CPU的時(shí)間片
- 搶占式調(diào)度模型。優(yōu)先讓優(yōu)先級(jí)高的線程使用CPU嘶炭,若相同抱慌,則隨機(jī)選擇,優(yōu)先級(jí)高的線程獲取CPU的時(shí)間片相對多一些眨猎。Java使用的是搶占式調(diào)度模型抑进。
設(shè)置線程優(yōu)先級(jí):
public final int getPriority(); //返回線程對象的優(yōu)先級(jí)。默認(rèn)優(yōu)先級(jí)是5睡陪。
public final void setPriority(); //設(shè)置線程的優(yōu)先級(jí)寺渗。
MAX_PRIORITY最大優(yōu)先級(jí)值是10
MIN_PRIORITY最小優(yōu)先級(jí)是1
NORM_PRIORITY默認(rèn)優(yōu)先級(jí)是5
7匿情、 線程控制
父類(Thread)方法:
- a. 線程休眠
public static void sleep(long millis);
//指定毫秒內(nèi)休眠
//自定義類中run()里調(diào)用 Thread.sleep(millis);
// 進(jìn)入阻塞狀態(tài),但是不釋放資源信殊,容易造成死鎖
b.線程加入
public final void join();
//等待該線程終止炬称,其他線程再開始
//主類中調(diào)用
c.線程禮讓
public static void yield();
//暫停當(dāng)前正在執(zhí)行的線程對象,并執(zhí)行其他線程
//自定義類中調(diào)用
//讓多個(gè)線程的執(zhí)行更和諧涡拘,但不能保證一個(gè)線程一次玲躯。
//釋放資源(CPU、內(nèi)存等)鳄乏,線程重新進(jìn)入【就緒】狀態(tài)跷车,讓相同優(yōu)先級(jí)或者高優(yōu)先級(jí)線程執(zhí)行
d.后臺(tái)線程
public final void setDaemon(boolean on);
//將該線程標(biāo)記為守護(hù)線程或用戶線程,當(dāng)正在運(yùn)行的線程都是守護(hù)線程時(shí)(即主線程滅亡汞窗,守護(hù)線程隨之消失)姓赤,Java虛擬機(jī)退出
//該方法必須在啟動(dòng)線程前調(diào)用
//主類中調(diào)用
e.中斷線程
public final void stop();
//該方法已過時(shí),但還可以使用仲吏。不建議使用不铆,顯示stop();
//多長時(shí)間線程沒有進(jìn)行就結(jié)束了
//主類中調(diào)用
public void interrupt();
//把線程的狀態(tài)終止,拋出異常InterruptedException