【Java多線程】之1進(jìn)程與線程概述

該系列博客轉(zhuǎn)載于博客https://www.cnblogs.com/xrq730,為原博客博主點(diǎn)贊

進(jìn)程與線程

談到多線程抹恳,就得先講進(jìn)程和線程的概念骂维。

進(jìn)程

進(jìn)程可以理解為受操作系統(tǒng)管理的基本運(yùn)行單元。360瀏覽器是一個(gè)進(jìn)程扼脐、WPS也是一個(gè)進(jìn)程肠仪,正在操作系統(tǒng)中運(yùn)行的".exe"都可以理解為一個(gè)進(jìn)程肖抱。

線程

進(jìn)程中獨(dú)立運(yùn)行的子任務(wù)就是一個(gè)線程。像QQ.exe運(yùn)行的時(shí)候就有很多子任務(wù)在運(yùn)行异旧,比如聊天線程意述、好友視頻線程、下載文件線程等等泽艘。

為什么要使用多線程

如果使用得當(dāng)欲险,線程可以有效地降低程序的開發(fā)和維護(hù)等成本,同時(shí)提升復(fù)雜應(yīng)用程序的性能匹涮。具體說,線程的優(yōu)勢(shì)有:

發(fā)揮多處理器的強(qiáng)大能力

現(xiàn)在槐壳,多處理器系統(tǒng)正日益盛行然低,并且價(jià)格不斷降低,即時(shí)在低端服務(wù)器和中斷桌面系統(tǒng)中,通常也會(huì)采用多個(gè)處理器雳攘,這種趨勢(shì)還在進(jìn)一步加快带兜,因?yàn)橥ㄟ^提高時(shí)鐘頻率來提升性能已變得越來越困難,處理器生產(chǎn)廠商都開始轉(zhuǎn)而在單個(gè)芯片上放置多個(gè)處理器核吨灭。試想刚照,如果只有單個(gè)線程,雙核處理器系統(tǒng)上程序只能使用一半的CPU資源喧兄,擁有100個(gè)處理器的系統(tǒng)上將有99%的資源無法使用无畔。多線程程序則可以同時(shí)在多個(gè)處理器上執(zhí)行,如果設(shè)計(jì)正確吠冤,多線程程序可以通過提高處理器資源的利用率來提升系統(tǒng)吞吐率浑彰。

在單處理器系統(tǒng)上獲得更高的吞吐率

如果程序是單線程的,那么當(dāng)程序等待某個(gè)同步I/O操作完成時(shí)拯辙,處理器將處于空閑狀態(tài)郭变。而在多線程程序中,如果一個(gè)線程在等待I/O操作完成涯保,另一個(gè)線程可以繼續(xù)運(yùn)行诉濒,使得程序能在I/O阻塞期間繼續(xù)運(yùn)行。

建模的簡(jiǎn)單性

通過使用線程夕春,可以將復(fù)雜并且異步的工作流進(jìn)一步分解為一組簡(jiǎn)單并且同步的工作流未荒,每個(gè)工作流在一個(gè)單獨(dú)的線程中運(yùn)行,并在特定的同步位置進(jìn)行交互撇他。我們可以通過一些現(xiàn)有框架來實(shí)現(xiàn)上述目標(biāo)茄猫,例如Servlet和RMI,框架負(fù)責(zé)解決一些細(xì)節(jié)問題困肩,例如請(qǐng)求管理划纽、線程創(chuàng)建、負(fù)載平衡锌畸,并在正確的時(shí)候?qū)⒄?qǐng)求分發(fā)給正確的應(yīng)用程序組件勇劣。編寫Servlet的開發(fā)人員不需要了解多少請(qǐng)求在同一時(shí)刻要被處理,也不需要了解套接字的輸入流或輸出流是否被阻塞潭枣,當(dāng)調(diào)用Servlet的service方法來響應(yīng)Web請(qǐng)求時(shí)比默,可以以同步的方式來處理這個(gè)請(qǐng)求,就好像它是一個(gè)單線程程序盆犁。

異步事件的簡(jiǎn)化處理

服務(wù)器應(yīng)用程序在接受多個(gè)來自遠(yuǎn)程客戶端的套接字連接請(qǐng)求時(shí)命咐,如果為每個(gè)連接都分配其各自的線程并且使用同步I/O,那么就會(huì)降低這類程序的開發(fā)難度谐岁。如果某個(gè)應(yīng)用程序?qū)μ捉幼謭?zhí)行讀操作而此時(shí)還沒有數(shù)據(jù)到來醋奠,那么這個(gè)讀操作將一直阻塞榛臼,直到有數(shù)據(jù)到達(dá)。在單線程應(yīng)用程序中窜司,這不僅意味著在處理請(qǐng)求的過程中將停頓沛善,而且還意味著在這個(gè)線程被阻塞期間,對(duì)所有請(qǐng)求的處理都將停頓塞祈。為了避免這個(gè)問題金刁,單線程服務(wù)器應(yīng)用程序必須使用非阻塞I/O,但是這種I/O的復(fù)雜性要遠(yuǎn)遠(yuǎn)高于同步I/O议薪,并且很容易出錯(cuò)尤蛮。然而,如果每個(gè)請(qǐng)求都擁有自己的處理線程笙蒙,那么在處理某個(gè)請(qǐng)求時(shí)發(fā)生的阻塞將不會(huì)影響其他請(qǐng)求的處理抵屿。

創(chuàng)建線程的方式

創(chuàng)建線程有兩種方式:

繼承Thread,重寫父類的run()方法

public class MyThread00 extends Thread
{        
    public void run()
    {
        for (int i = 0; i < 5; i++)
        {
            System.out.println(Thread.currentThread().getName() + "在運(yùn)行!");
        }
    }
}
public static void main(String[] args)
{
    MyThread01 mt0 = new MyThread01();
    Thread t = new Thread(mt0);
    t.start();
        
    for (int i = 0; i < 5; i++)
    {
        System.out.println(Thread.currentThread().getName() + "在運(yùn)行捅位!");
    }
}

看一下運(yùn)行結(jié)果:

main在運(yùn)行轧葛!
Thread-0在運(yùn)行!
main在運(yùn)行!
Thread-0在運(yùn)行!
main在運(yùn)行艇搀!
Thread-0在運(yùn)行!
main在運(yùn)行尿扯!
Thread-0在運(yùn)行!
main在運(yùn)行!
Thread-0在運(yùn)行!

看到main線程和Thread-0線程交替運(yùn)行焰雕,效果十分明顯衷笋。

有可能有些人看不到這么明顯的效果,這也很正常矩屁。所謂的多線程辟宗,指的是兩個(gè)線程的代碼可以同時(shí)運(yùn)行,而不必一個(gè)線程需要等待另一個(gè)線程內(nèi)的代碼執(zhí)行完才可以運(yùn)行吝秕。對(duì)于單核CPU來說泊脐,是無法做到真正的多線程的,每個(gè)時(shí)間點(diǎn)上烁峭,CPU都會(huì)執(zhí)行特定的代碼容客,由于CPU執(zhí)行代碼時(shí)間很快,所以兩個(gè)線程的代碼交替執(zhí)行看起來像是同時(shí)執(zhí)行的一樣约郁。那具體執(zhí)行某段代碼多少時(shí)間缩挑,就和分時(shí)機(jī)制系統(tǒng)有關(guān)了。分時(shí)系統(tǒng)把CPU時(shí)間劃分為多個(gè)時(shí)間片鬓梅,操作系統(tǒng)以時(shí)間片為單位片為單位各個(gè)線程的代碼供置,越好的CPU分出的時(shí)間片越小。所以看不到明顯效果也很正常绽快,一個(gè)線程打印5句話本來就很快士袄,可能在分出的時(shí)間片內(nèi)就執(zhí)行完成了悲关。所以谎僻,最簡(jiǎn)單的解決辦法就是把for循環(huán)的值調(diào)大一點(diǎn)就可以了(也可以在for循環(huán)里加Thread.sleep方法娄柳,這個(gè)之后再說)。

實(shí)現(xiàn)Runnable接口

和繼承自Thread類差不多艘绍,不過實(shí)現(xiàn)Runnable后赤拒,還是要通過一個(gè)Thread來啟動(dòng)

public class MyThread01 implements Runnable
{
    public void run()
    {
        for (int i = 0; i < 5; i++)
        {
            System.out.println(Thread.currentThread().getName() + "在運(yùn)行!");
        }
    }
}
public class MyThread01 implements Runnable
{
    public void run()
    {
        for (int i = 0; i < 5; i++)
        {
            System.out.println(Thread.currentThread().getName() + "在運(yùn)行!");
        }
    }
}

效果也十分明顯:

main在運(yùn)行!
Thread-0在運(yùn)行!
main在運(yùn)行诱鞠!
Thread-0在運(yùn)行!
main在運(yùn)行挎挖!
Thread-0在運(yùn)行!
main在運(yùn)行!
Thread-0在運(yùn)行!
main在運(yùn)行航夺!
Thread-0在運(yùn)行!

兩種多線程實(shí)現(xiàn)方式的對(duì)比

看一下Thread類的API:


image

其實(shí)Thread類也是實(shí)現(xiàn)的Runnable接口蕉朵。兩種實(shí)現(xiàn)方式對(duì)比的關(guān)鍵就在于extends和implements的對(duì)比,當(dāng)然是后者好阳掐。因?yàn)榈谝皇夹疲^承只能單繼承,實(shí)現(xiàn)可以多實(shí)現(xiàn)缭保;第二汛闸,實(shí)現(xiàn)的方式對(duì)比繼承的方式,也有利于減小程序之間的耦合艺骂。
因此诸老,多線程的實(shí)現(xiàn)幾乎都是使用的Runnable接口的方式。不過钳恕,后面的文章别伏,為了簡(jiǎn)單,就用繼承Thread類的方式了忧额。

線程狀態(tài)

虛擬機(jī)中的線程狀態(tài)有六種厘肮,定義在Thread.State中:

1、新建狀態(tài)NEW

new了但是沒有啟動(dòng)的線程的狀態(tài)宙址。比如"Thread t = new Thread()"轴脐,t就是一個(gè)處于NEW狀態(tài)的線程

2、可運(yùn)行狀態(tài)RUNNABLE

new出來線程抡砂,調(diào)用start()方法即處于RUNNABLE狀態(tài)了大咱。處于RUNNABLE狀態(tài)的線程可能正在Java虛擬機(jī)中運(yùn)行,也可能正在等待處理器的資源注益,因?yàn)橐粋€(gè)線程必須獲得CPU的資源后碴巾,才可以運(yùn)行其run()方法中的內(nèi)容,否則排隊(duì)等待

3丑搔、阻塞BLOCKED

如果某一線程正在等待監(jiān)視器鎖厦瓢,以便進(jìn)入一個(gè)同步的塊/方法提揍,那么這個(gè)線程的狀態(tài)就是阻塞BLOCKED

4、等待WAITING

某一線程因?yàn)檎{(diào)用不帶超時(shí)的Object的wait()方法煮仇、不帶超時(shí)的Thread的join()方法劳跃、LockSupport的park()方法,就會(huì)處于等待WAITING狀態(tài)

5浙垫、超時(shí)等待TIMED_WAITING

某一線程因?yàn)檎{(diào)用帶有指定正等待時(shí)間的Object的wait()方法刨仑、Thread的join()方法、Thread的sleep()方法夹姥、LockSupport的parkNanos()方法杉武、LockSupport的parkUntil()方法,就會(huì)處于超時(shí)等待TIMED_WAITING狀態(tài)

6辙售、終止?fàn)顟B(tài)TERMINATED
線程調(diào)用終止或者run()方法執(zhí)行結(jié)束后轻抱,線程即處于終止?fàn)顟B(tài)。處于終止?fàn)顟B(tài)的線程不具備繼續(xù)運(yùn)行的能力

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旦部,一起剝皮案震驚了整個(gè)濱河市祈搜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌志鹃,老刑警劉巖夭问,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異曹铃,居然都是意外死亡缰趋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門陕见,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秘血,“玉大人,你說我怎么就攤上這事评甜』伊福” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵忍坷,是天一觀的道長(zhǎng)粘舟。 經(jīng)常有香客問我,道長(zhǎng)佩研,這世上最難降的妖魔是什么柑肴? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮旬薯,結(jié)果婚禮上晰骑,老公的妹妹穿的比我還像新娘。我一直安慰自己绊序,他們只是感情好硕舆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布秽荞。 她就那樣靜靜地躺著,像睡著了一般抚官。 火紅的嫁衣襯著肌膚如雪扬跋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天耗式,我揣著相機(jī)與錄音胁住,去河邊找鬼。 笑死刊咳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的儡司。 我是一名探鬼主播娱挨,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼捕犬!你這毒婦竟也來了跷坝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤碉碉,失蹤者是張志新(化名)和其女友劉穎柴钻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垢粮,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贴届,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜡吧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毫蚓。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖昔善,靈堂內(nèi)的尸體忽然破棺而出元潘,到底是詐尸還是另有隱情,我是刑警寧澤君仆,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布翩概,位于F島的核電站,受9級(jí)特大地震影響返咱,放射性物質(zhì)發(fā)生泄漏钥庇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一洛姑、第九天 我趴在偏房一處隱蔽的房頂上張望上沐。 院中可真熱鬧,春花似錦楞艾、人聲如沸参咙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蕴侧。三九已至择同,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間净宵,已是汗流浹背敲才。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留择葡,地道東北人紧武。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像敏储,于是被迫代替她去往敵國(guó)和親阻星。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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

  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    勝浩_ae28閱讀 5,110評(píng)論 0 23
  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記已添,整理的知識(shí)點(diǎn)妥箕,也是為了防止忘記,尊重勞動(dòng)成果更舞,轉(zhuǎn)載注明出處哦畦幢!如果你也喜歡,那...
    波波波先森閱讀 11,268評(píng)論 4 56
  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    小徐andorid閱讀 2,810評(píng)論 3 53
  • 單任務(wù) 單任務(wù)的特點(diǎn)是排隊(duì)執(zhí)行缆蝉,也就是同步宇葱,就像再cmd輸入一條命令后,必須等待這條命令執(zhí)行完才可以執(zhí)行下一條命令...
    Steven1997閱讀 1,178評(píng)論 0 6
  • 文 | 引薦 二十五年前,杏樹彎的楊林外出時(shí)芽偏,在三叉路口旁撿了一個(gè)棄嬰雷逆,弱瘦體痿∥畚荆看起來像養(yǎng)不活的樣子膀哲,眾鄉(xiāng)親都勸...
    生活簡(jiǎn)單多些付出閱讀 399評(píng)論 0 0