2019-05-09


多線程


1.程序與進(jìn)程:程序就是一堆靜態(tài)的代碼歪泳,存儲在硬盤上,程序如果不運(yùn)行露筒,本質(zhì)就是一個文件呐伞,程序一旦運(yùn)行產(chǎn)生進(jìn)程,進(jìn)程一直向前運(yùn)行慎式,直到進(jìn)程結(jié)束伶氢。

2.操作系統(tǒng)的發(fā)展:單任務(wù)操作系統(tǒng):一段時間只能運(yùn)行一個程序(任務(wù))CPU利用率極低。引入進(jìn)程的概念:把程序的一次運(yùn)行產(chǎn)生進(jìn)程(內(nèi)存空間瘪吏。資源癣防。程序的執(zhí)行堆棧)進(jìn)程作為操作系統(tǒng)分配資源的基本單位。多任務(wù)操作系統(tǒng):一臺電腦就一個CPU掌眠,多個任務(wù)輪流使用CPU蕾盯,從宏觀上看,一段時間有多個任務(wù)正在運(yùn)行蓝丙,從微觀上看级遭,一個車時間點(diǎn)只有一個任務(wù)在運(yùn)行。CPU時間片:多個進(jìn)程通過CPU時間片輪轉(zhuǎn)實現(xiàn)多任務(wù)渺尘。這種現(xiàn)象稱為并發(fā)操作装畅。并行:一個時間段,多個任務(wù)同時運(yùn)行沧烈,多個CPU運(yùn)行各自的進(jìn)程。線程的引入解決實時性的問題像云。

3.進(jìn)程和線程的區(qū)別


? ?4.多線程實現(xiàn):thread類位于Java.lang包中锌雀,表示進(jìn)程中的執(zhí)行線程。實現(xiàn)多線程有兩種方式迅诬;1.繼承thread腋逆,main主線程和其它定義線程搶CPU執(zhí)行。多線程在提升CPU利用率的同時侈贷,增加程序的復(fù)雜度惩歉。2.實現(xiàn)runnable接口:共享資源

結(jié)論:1.多線程搶占CPU執(zhí)行,可能在任意位置被切換出去(掛起);

? ? ? ? ? ? 2.多線程搶占CPU后撑蚌,從上次掛起的位置開始執(zhí)行(先回復(fù)上次的執(zhí)行堆棧)

? ? ? ? ? ? 3.多線程都可以獨(dú)立運(yùn)行上遥,相互不干擾,多個線程都可以能訪問共享資源争涌,很容易導(dǎo)致數(shù)據(jù)錯亂粉楚。

5.現(xiàn)成的聲明周期

5.1新生狀態(tài):用new關(guān)鍵字建立一個線程后,該線程對象就處于新生狀態(tài)亮垫,處于新生狀態(tài)的線程有自己的內(nèi)存空間模软,通過吊用start()方法進(jìn)入就緒狀態(tài)。

5.2就緒狀態(tài):處于就緒狀態(tài)線程具備了運(yùn)行條件饮潦,但還沒分配到CPU燃异,處于線程就緒隊列,等待系統(tǒng)為其分配CPU继蜡,當(dāng)系統(tǒng)選定一個等待執(zhí)行的線程后回俐,他就會從就緒狀態(tài)進(jìn)入執(zhí)行狀態(tài),該動作稱為CPU調(diào)度

5.3運(yùn)行狀態(tài):在運(yùn)行狀態(tài)的線程執(zhí)行自己的run方法中代碼壹瘟,直到等待某資源而阻塞? ? 或完成任何而死亡鲫剿,如果在給定的時間片內(nèi)沒有執(zhí)行結(jié)束,就會被系統(tǒng)給換下來回到等待執(zhí)行狀態(tài)稻轨。

5.4阻塞狀態(tài):處于運(yùn)行狀態(tài)的線程在某些情況下灵莲,如執(zhí)行了sleep(睡眠)方法,或等待I/O設(shè)備等資源殴俱,將讓出CPU并暫時停止自己運(yùn)行政冻,進(jìn)入阻塞狀態(tài)。在阻塞狀態(tài)的線程不能進(jìn)入就緒隊列线欲。只有當(dāng)引起阻塞的原因消除時明场,如睡眠時間已到,或等待的I/O設(shè)備空閑下來李丰,線程便轉(zhuǎn)入就緒狀態(tài)苦锨,重新到就緒隊列中排隊等待,被系統(tǒng)選中后從原來停止的位置開始繼續(xù)執(zhí)行趴泌。

5.5死亡狀態(tài):死亡狀態(tài)是線程生命周期中的最后一個階段舟舒。線程死亡的原因有三個,一個是正常運(yùn)行的線程完成了它的全部工作嗜憔;另一個是線程被強(qiáng)制性地終止秃励,如通過stop方法來終止一個線程【不推薦使用】;三是線程拋出未捕獲的異常吉捶。

”6.線程常用方法:1.線程優(yōu)先級:線程優(yōu)先級高夺鲜,被CPU調(diào)度的幾率大皆尔,并不表示一定先運(yùn)行。

System.out.println(Thread.MIN_PRIORITY);

System.out.println(Thread.MAX_PRIORITY);

System.out.println(Thread.NORM_PRIORITY);

//主線程的優(yōu)先級(默認(rèn)優(yōu)先級)

System.out.println(Thread.currentThread().getPriority());

Thread01 t1?= new?Thread01();

//設(shè)置線程的優(yōu)先級

t1.setPriority(Thread.MAX_PRIORITY);

t1.start();

Thread01 t2?= new?Thread01();

//設(shè)置線程的優(yōu)先級

t2.setPriority(Thread.MIN_PRIORITY);

t2.start();

2.isalive:判斷? ? 線程是否處于活動狀態(tài)币励,線程調(diào)用start之后就處于活動狀態(tài)慷蠕。

Thread01 t1?= new?Thread01();

System.out.println(t1.isAlive());

//設(shè)置線程的優(yōu)先級

t1.setPriority(Thread.MAX_PRIORITY);

t1.start();

System.out.println(t1.isAlive());

3.join:調(diào)用該方法的線程強(qiáng)制執(zhí)行,其它線程處于阻塞狀態(tài)榄审,該線程執(zhí)行完畢后砌们,其它? ?線程再執(zhí)行join稱為線程的強(qiáng)制執(zhí)行,有可能被外界中斷產(chǎn)生InterruptedException 中斷異常搁进。

public?class?Test02 {

public?static?void?main(String[] args){

Thread02 t?= new?Thread02("線程A");

t.start();

for?(int?i?= 0; i?< 5; i++) {

if(i?== 2) {

try?{

t.join();

} catch?(InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName() + "->"?+ i);

}

}

}

4.sleep:在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠浪感,休眠的線程進(jìn)入阻塞狀態(tài)

public?static?void?main(String[] args) {

Thread03 t?= new?Thread03("線程A");

t.start();

Thread mainThread?= Thread.currentThread();

System.out.println(mainThread.getName()+"即將進(jìn)入休眠");

try?{

Thread.sleep(5000);

} catch?(InterruptedException e) {

e.printStackTrace();

}

//中斷線程

t.interrupt();

System.out.println(mainThread.getName()+"休眠完成");

}

5.yield:A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.當(dāng)前線程給cpu調(diào)度器一個暗示,暗示其想禮讓一次其擁有的cpu饼问,CPU調(diào)度者也可以狐貍這次暗示影兽。此時當(dāng)前線程進(jìn)入就緒狀態(tài)。

public?static?void?main(String[] args) {


Thread mainThread?= Thread.currentThread();


Thread04 t?= new?Thread04("線程A");

t.start();


for?(int?i?= 0; i?< 5; i++) {

if?(i?== 2) {

// yield使當(dāng)前禮讓一次

Thread.yield();

}

System.out.println(mainThread.getName() + "->"?+ i);

}

}

6.線程的終止:目前而言莱革,不推薦使用stop直接終止線程峻堰。用interrupt()方法去中斷正在執(zhí)行的線程,而在線程內(nèi)部一定要寫捕獲中斷的異常盅视。通過異常處理機(jī)制正常結(jié)束線程捐名。

7.線程的安全問題:線程在執(zhí)行過程中,通過cpu的調(diào)度闹击,執(zhí)行軌跡不確定镶蹋,對共享資源的訪問很容易造成數(shù)據(jù)的錯誤。我們稱這個錯亂稱為線程安全問題赏半。

1.同步概念:原子性操作:一個操作要么一次性做完贺归,要么根本不開始,不存在中間狀態(tài)断箫。同步就是讓操作保持原子性拂酣!java提供兩種方式實現(xiàn)同步。1.同步代碼塊synchronized(obj){}中的obj稱為同步監(jiān)視器.同步代碼塊中同步監(jiān)視器可以是任何對象仲义,但是推薦使用共享資源作為同步監(jiān)視器

把所有的同步操作放到同步代碼塊中婶熬,

synchronized?(mutex) {

???// .. .

}


mutex稱為互斥鎖/同步鎖。對共享資源進(jìn)行加鎖實現(xiàn)同步埃撵。一般用共享資源作為同步鎖尸诽,也稱同步監(jiān)視器。

public?class?MyRun implements?Runnable {

//共享資源

private?int?count?= 5;


@Override

public?void?run() {

//模擬一個窗口5個人

for?(int?i?= 0; i?< 5; i++) {

//同步代碼塊

// mutex?互斥鎖

synchronized?(this) {

if?(count?> 0) {

try?{

Thread.sleep(3000);

count--;

} catch?(InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"賣出一張票盯另,還剩"?+ count?+ "張票");

2.同步方法:如果同步代碼(原子性)很多,可以考慮使用同步方法洲赵。把普通方法用?synchronized修飾鸳惯,同步方法的同步監(jiān)視器是this商蕴。

Public?class?MyRun implements?Runnable {

//共享資源

private?int?count?= 5;


@Override

public?void?run() {

//模擬一個窗口5個人

for?(int?i?= 0; i?< 5; i++) {

this.saleTicket();

}

}

//同步方法默認(rèn)對this加鎖

private?synchronized?void?saleTicket() {

if?(count?> 0) {

try?{

Thread.sleep(3000);

count--;

} catch?(InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"賣出一張票,還剩"?+ count?+ "張票");

8.死鎖:線程t1芝发,擁有A資源绪商,再次申請B資源,線程t2,擁有B資源辅鲸,再申請A資源格郁,t1因為沒有申請到B資源而進(jìn)入阻塞;t2因為沒有申請到A資源進(jìn)入阻塞独悴。此時兩個線程都處于阻塞狀態(tài)而不能正常結(jié)束例书,而此時cpu空轉(zhuǎn),這種情況稱為死鎖刻炒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末决采,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子坟奥,更是在濱河造成了極大的恐慌树瞭,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爱谁,死亡現(xiàn)場離奇詭異晒喷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)访敌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門朴读,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唠帝,“玉大人,你說我怎么就攤上這事『钏” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵棺亭,是天一觀的道長湾戳。 經(jīng)常有香客問我,道長叮姑,這世上最難降的妖魔是什么唉地? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮传透,結(jié)果婚禮上耘沼,老公的妹妹穿的比我還像新娘。我一直安慰自己朱盐,他們只是感情好群嗤,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兵琳,像睡著了一般狂秘。 火紅的嫁衣襯著肌膚如雪骇径。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天者春,我揣著相機(jī)與錄音破衔,去河邊找鬼。 笑死钱烟,一個胖子當(dāng)著我的面吹牛晰筛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拴袭,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼读第,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了稻扬?” 一聲冷哼從身側(cè)響起卦方,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泰佳,沒想到半個月后盼砍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逝她,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年浇坐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黔宛。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡近刘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出臀晃,到底是詐尸還是另有隱情觉渴,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布徽惋,位于F島的核電站案淋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏险绘。R本人自食惡果不足惜踢京,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宦棺。 院中可真熱鬧瓣距,春花似錦、人聲如沸代咸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逻杖,卻和暖如春慨默,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弧腥。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潮太,地道東北人管搪。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像铡买,于是被迫代替她去往敵國和親更鲁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容