Java并發(fā)編程基礎(chǔ)(一)線程簡介

一贤笆、什么是線程


現(xiàn)代操作系統(tǒng)調(diào)度的最小單元是線程府树,在一個進(jìn)程里可以創(chuàng)建多個線程,這些線程都擁有各自的計(jì)數(shù)器偎蘸、堆棧和局部變量等屬性庄蹋,并且能夠訪問共享的內(nèi)存變量瞬内。處理器在這些線程上高速切換,讓使用者感覺到這些線程在同時執(zhí)行限书。

二虫蝶、為什么要使用多線程


  • 更多的處理器核心

一個單線程程序在運(yùn)行時只能使用一個處理器核心,那么再多的處理器核心加入也無法顯著提升該程序的執(zhí)行效率倦西。相反能真,如果該程序使用多線程技術(shù),將計(jì)算邏輯分配到多個處理器核心上扰柠,就會顯著減少程序的處理時間粉铐,并且隨著更多處理器核心的加入而變得更有效率。

  • 更快的響應(yīng)時間

有時我們會編寫業(yè)務(wù)較為復(fù)雜的代碼卤档。例如蝙泼,一筆訂單的創(chuàng)建,它包括插入訂單數(shù)據(jù)劝枣、生成訂單快照汤踏、發(fā)送郵件通知賣家和記錄貨品銷售數(shù)量∩诿猓可以使用多線程技術(shù)茎活,將數(shù)據(jù)一致性不強(qiáng)的操作派發(fā)給其他線程處理(也可以使用消息隊(duì)列),如生成訂單快照琢唾、發(fā)送郵件等载荔。好處是響應(yīng)用戶請求的線程能夠盡可能快地處理完成,縮短了響應(yīng)時間采桃,提升用戶體驗(yàn)懒熙。

三、線程優(yōu)先級


現(xiàn)代操作系統(tǒng)基本采用分時的形式調(diào)度運(yùn)行線程普办,操作系統(tǒng)會分出一個個時間片工扎,線程會分配到若干時間片,當(dāng)線程的時間片用完了就會發(fā)生線程調(diào)度衔蹲,等待下次分配肢娘。線程優(yōu)先級就是決定線程需要多或者少分配一些處理器資源的線程屬性。

通過一個整型成員變量priority來控制優(yōu)先級舆驶,優(yōu)先級范圍從1~10橱健,在線程構(gòu)建時可以通過setPriority(int)方法來修改線程優(yōu)先級,默認(rèn)優(yōu)先級是5沙廉。線程優(yōu)先級不能作為程序正確性的依賴拘荡,許多操作系統(tǒng)都是完全不理會Java線程對于優(yōu)先級的設(shè)定的。

四撬陵、線程的狀態(tài)


狀態(tài)名稱 說明
NEW 初始狀態(tài)珊皿,線程被構(gòu)建网缝,但是還沒有調(diào)用start()方法
RUNNABLE 運(yùn)行狀態(tài),就緒和 運(yùn)行中兩種狀態(tài)都稱作運(yùn)行中
BLOCKED 阻塞狀態(tài)蟋定,標(biāo)識線程阻塞于鎖
WAITING 等待狀態(tài)粉臊,表示線程進(jìn)入等待狀態(tài),進(jìn)入該狀態(tài)表示當(dāng)前線程需要等待其他線程做出一些特定動作(通知或中斷)
TIME_WAITING 超時等待狀態(tài)溢吻,不同于WAITING维费,它可以在指定時間自行返回
TERMINATED 終止?fàn)顟B(tài),表示當(dāng)前線程已經(jīng)執(zhí)行完畢
// ThreadState.java
public class ThreadState {
    
    public static void main(String[] args) {
        new Thread(new TimeWaiting(), "TimeWaitingThread").start();
        new Thread(new Waiting(), "WaitingThread").start();
        // 使用兩個Blocked線程, 一個獲取鎖成功, 另一個被阻塞
        new Thread(new Blocked(), "BlockedThread-1").start();
        new Thread(new Blocked(), "BlockedThread-2").start();
    }
    
    // 該線程不斷的進(jìn)行睡眠
    static class TimeWaiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                SleepUtils.second(100);
            }
        }
    }
    
    // 該線程在Waiting.class實(shí)例上等待
    static class Waiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (Waiting.class) {
                    try {
                        Waiting.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    // 該線程在Blocked.class 實(shí)例上加鎖后,不會釋放該鎖
    static class Blocked implements Runnable {
        public void run() {
            synchronized (Blocked.class) {
                while (true) {
                    SleepUtils.second(100);
                }
            }
        }
    }
    

}
// SleepUtils.java
public class SleepUtils {
    
    public static final void second(long seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            
        }
    }

}

命令行輸入“jps”促王,得到ThreadState的進(jìn)程id(如929)后,輸入“jstack 929”而晒,嘗試查看示例進(jìn)程運(yùn)行時的線程信息:

// BlockedThread-2 線程阻塞在獲取Blocked.class示例的鎖上
"BlockedThread-2" prio=5 tid=0x00007feacb05d000 nid=0x5d03 waiting for monitor entry 
[0x000000010fd58000]
        java.lang.Thread.State: BLOCKED (on object monitor)

// BlockedThread-1 線程獲取到了Blocked.class的鎖
"BlockedThread-1" prio=5 tid=0x00007feacb05a000 nid=0x5b03 waiting on condition
[0x000000010fc55000]
        java.lang.Thread.State: TIME_WAITING (sleeping)

// WaitingThread線程在Waiting實(shí)例上等待
"WaitingThread" prio=5 tid=0x00007feacb059800 nid=0x5903 in Object.wait()
[0x000000010fb52000]
        java.lang.Thread.State: WAITING (on object monitor)

// TimeWaitingThread 線程處于超時等待
"TimeWaitingThread" prio=5 tid=0x00007feacb058800 nid=0x5703 waiting on condition
[0x000000010fa4f000]
        java.lang.Thread.State: TIMED_WAITING (sleeping)
java線程狀態(tài)變遷

五蝇狼、守護(hù)線程


Daemon線程是一種支持型線程,因?yàn)樗饕挥米鞒绦蛑泻笈_調(diào)度以及支持性工作倡怎。這意味著迅耘,當(dāng)一個Java虛擬機(jī)中不存在非Daemon線程的時候,Java虛擬機(jī)將會退出监署。因此颤专,不能依靠Daemon線程的finally塊中的內(nèi)容來確保執(zhí)行關(guān)閉或清理資源的邏輯。
可以通過Thread.setDaemon(true)將線程設(shè)置為Daemon線程钠乏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末栖秕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子晓避,更是在濱河造成了極大的恐慌簇捍,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俏拱,死亡現(xiàn)場離奇詭異暑塑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锅必,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門事格,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搞隐,你說我怎么就攤上這事驹愚。” “怎么了尔许?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵么鹤,是天一觀的道長。 經(jīng)常有香客問我味廊,道長蒸甜,這世上最難降的妖魔是什么棠耕? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮柠新,結(jié)果婚禮上窍荧,老公的妹妹穿的比我還像新娘。我一直安慰自己恨憎,他們只是感情好蕊退,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著憔恳,像睡著了一般瓤荔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钥组,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天输硝,我揣著相機(jī)與錄音,去河邊找鬼程梦。 笑死点把,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屿附。 我是一名探鬼主播郎逃,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挺份!你這毒婦竟也來了褒翰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤压恒,失蹤者是張志新(化名)和其女友劉穎影暴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體探赫,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡型宙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了伦吠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妆兑。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖毛仪,靈堂內(nèi)的尸體忽然破棺而出搁嗓,到底是詐尸還是另有隱情,我是刑警寧澤箱靴,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布腺逛,位于F島的核電站,受9級特大地震影響衡怀,放射性物質(zhì)發(fā)生泄漏棍矛。R本人自食惡果不足惜安疗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望够委。 院中可真熱鬧荐类,春花似錦、人聲如沸茁帽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潘拨。三九已至吊输,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铁追,已是汗流浹背璧亚。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脂信,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓透硝,卻偏偏與公主長得像狰闪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子濒生,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

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