第四章_Java 并發(fā)編程基礎(chǔ)

線程簡(jiǎn)介

線程優(yōu)先級(jí)

在 Java 線程中,通過一個(gè)整形成員變量 priority 來控制優(yōu)先級(jí)妖啥,優(yōu)先級(jí)的范圍從 1~10霉颠,在線程構(gòu)建的時(shí)候可以通過 setPriority(int)方法來修改優(yōu)先級(jí),默認(rèn)優(yōu)先級(jí)是 5荆虱,優(yōu)先級(jí)高的線程比優(yōu)先級(jí)低的線程要分配更多的時(shí)間片蒿偎。設(shè)置線程優(yōu)先級(jí)時(shí)朽们,針對(duì)頻繁阻塞(休眠或者 I/O 操作)的線程需要設(shè)置較高的優(yōu)先級(jí),而偏重計(jì)算(需要較多 CPU 時(shí)間或者偏運(yùn)算)的線程則設(shè)置較低的優(yōu)先級(jí)诉位,確保處理器不會(huì)被獨(dú)占骑脱。

線程優(yōu)先級(jí)不能作為程序正確性的依賴,因?yàn)椴僮飨到y(tǒng)可以完全不同理會(huì) Java 線程對(duì)于優(yōu)先級(jí)的設(shè)定苍糠。

線程的狀態(tài)
狀態(tài) 說明
NEW 初始狀態(tài)叁丧,線程被構(gòu)建,但是還沒有調(diào)用 start 方法
RUNNABLE 運(yùn)行狀態(tài)岳瞭,Java 線程將操作系統(tǒng)中的就緒和運(yùn)行兩種狀態(tài)籠統(tǒng)的稱為運(yùn)行中
BLOCKED 阻塞狀態(tài)拥娄,表示線程阻塞于鎖
WAITING 等待狀態(tài),表示線程進(jìn)入等待狀態(tài)瞳筏,進(jìn)入該狀態(tài)表示當(dāng)前線程需要
TIME_WAITING 超時(shí)等待狀態(tài)稚瘾,該狀態(tài)不同于 WAITING,它可以在指定的時(shí)間自行返回的
TEAMINATED 終止?fàn)顟B(tài)姚炕,表示當(dāng)前線程已經(jīng)執(zhí)行完畢
image

線程在創(chuàng)建之后孟抗,調(diào)用 start 方法開始運(yùn)行。當(dāng)線程執(zhí)行 wait 方法之后钻心,線程進(jìn)入等待狀態(tài)凄硼。進(jìn)入等待狀態(tài)的線程需要依靠其他線程的通知才能返回運(yùn)行狀態(tài),而超時(shí)等待狀態(tài)相當(dāng)于等待狀態(tài)的基礎(chǔ)上增加了超時(shí)限制捷沸,也就是超時(shí)時(shí)間到達(dá)時(shí)將會(huì)返回到運(yùn)行狀態(tài)摊沉。當(dāng)線程調(diào)用同步方法時(shí),在沒有獲取鎖的情況下痒给,線程將會(huì)進(jìn)入阻塞狀態(tài)说墨。線程在執(zhí)行 Runnable 的 run 方法之后將會(huì)進(jìn)入到終止?fàn)顟B(tài)。

注意:Java 將操作系統(tǒng)中的運(yùn)行和就緒兩種狀態(tài)合并為運(yùn)行狀態(tài)苍柏。阻塞狀態(tài)是線程阻塞在進(jìn)入synchronized 關(guān)鍵字修飾的方法或代碼塊時(shí)的狀態(tài)尼斧,但是阻塞在 java.concurrent 包中 Lock 接口的線程狀態(tài)卻是等待狀態(tài),因?yàn)?java.concurrent 包中 Lock 接口對(duì)于阻塞的實(shí)現(xiàn)均使用了 LockSupport 類中的相關(guān)方法试吁。

Daemon 線程

Daemon 線程是一種支持型線程棺棵,因?yàn)樗饕挥米鞒绦蛑泻笈_(tái)調(diào)度以及支持性工作。這意味著熄捍,當(dāng)一個(gè) Java 虛擬機(jī)不存在非 Daemon 線程的時(shí)候烛恤,Java 虛擬機(jī)將會(huì)退出∮嗟ⅲ可以通過調(diào)用 Thread.setDaemon(true) 將線程設(shè)置為 Daemon 線程缚柏。

Daemon 線程被用作完成支持型工作,所以在 Java 虛擬機(jī)退出時(shí) Daemon 線程中的 finally 塊不一定會(huì)執(zhí)行到碟贾。

public class DaemonDemo {
    public static void main(String[] args) {
        Thread thread=new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                System.out.println("Daemon");   //這一句實(shí)際上并沒有執(zhí)行到
            }
        });
        thread.setDaemon(true);
        thread.start();
    }
}

因此币喧,在構(gòu)建 Daemon 線程時(shí)轨域,不能依靠 finally 塊中的內(nèi)容來確保執(zhí)行關(guān)閉或者清理資源的邏輯。

線程的中斷

理解中斷

中斷可以理解為線程的一個(gè)標(biāo)識(shí)位屬性杀餐,它表示一個(gè)運(yùn)行中的線程是否被其他線程進(jìn)行了中斷操作疙挺。中斷好比其他線程對(duì)該線程打了招呼,其他線程通過調(diào)用該線程的 interrupt() 方法對(duì)其進(jìn)行中斷操作怜浅。

線程通過檢查自身是否被中斷來進(jìn)行響應(yīng)铐然,線程通過方法 isInterrupted() 來進(jìn)行判斷是否被中斷,也可以調(diào)用靜態(tài)方法 Thread.interrupted() 對(duì)當(dāng)前線程的中斷標(biāo)識(shí)位進(jìn)行復(fù)位恶座。如果該線程已經(jīng)處于終結(jié)狀態(tài)搀暑,即使該線程被中斷過,在調(diào)用對(duì)象的 isInterrupted() 時(shí)依舊會(huì)返回 false跨琳。

從 Java 的 API 中可以看到自点,許多聲明拋出 InterruptedException 的方法( 例如 Thread.sleep(long millis)方法 ),在這些方法拋出該異常之前脉让,Java 虛擬機(jī)會(huì)將該線程的中斷標(biāo)識(shí)位清楚桂敛,然后再拋出異常,此時(shí)調(diào)用 isInterrupted() 將會(huì)返回 false溅潜。

public class InterruptedDemo {
    public static void main(String[] args) {
        Thread threadA = new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(10);
                    int a = 0;  //讓線程具有實(shí)際的意義
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread threadB = new Thread(() -> {
            while (true) {

            }
        });
        threadA.start();
        threadB.start();
        try {
            Thread.sleep(2000); //讓線程 A 和 B 充分運(yùn)行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadA.interrupt();
        threadB.interrupt();
        System.out.println(threadA.isInterrupted());
        System.out.println(threadB.isInterrupted());
    }
}
/**
 * 輸出:
 * false
 * true
 */

可以看出拋出 InterruptedException 的線程標(biāo)志位被清除了术唬。

安全的中斷線程

可以使用標(biāo)識(shí)位來解決,其實(shí)和 interrupt 標(biāo)識(shí)位是一樣的原理滚澜,不過需要注意 interrupt 可以會(huì)因?yàn)閽伄惓6宄藰?biāo)識(shí)位粗仓。

public class SafelyStopThread {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new WorkRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(1000);
        ((WorkRunnable) runnable).setCancel(true);

        Runnable runnable1 = new WorkRunnable();
        Thread thread1 = new Thread(runnable1);
        thread1.start();
        Thread.sleep(1000);
        thread1.interrupt();
    }

    static class WorkRunnable implements Runnable {
        private long i;
        private volatile boolean isCancel = false;

        @Override
        public void run() {
            while (!isCancel && !Thread.currentThread().isInterrupted()) {
                i++;
            }
            System.out.println(i);
        }

        public void setCancel(boolean cancel) {
            isCancel = cancel;
        }
    }
}

線程間通信

下篇講(逃

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市设捐,隨后出現(xiàn)的幾起案子借浊,更是在濱河造成了極大的恐慌,老刑警劉巖萝招,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚂斤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡槐沼,警方通過查閱死者的電腦和手機(jī)曙蒸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來母赵,“玉大人逸爵,你說我怎么就攤上這事“汲埃” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵构韵,是天一觀的道長周蹭。 經(jīng)常有香客問我趋艘,道長,這世上最難降的妖魔是什么凶朗? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任瓷胧,我火速辦了婚禮,結(jié)果婚禮上棚愤,老公的妹妹穿的比我還像新娘搓萧。我一直安慰自己,他們只是感情好宛畦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布瘸洛。 她就那樣靜靜地躺著,像睡著了一般次和。 火紅的嫁衣襯著肌膚如雪反肋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天踏施,我揣著相機(jī)與錄音石蔗,去河邊找鬼。 笑死畅形,一個(gè)胖子當(dāng)著我的面吹牛养距,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播日熬,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼铃在,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了碍遍?” 一聲冷哼從身側(cè)響起定铜,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怕敬,沒想到半個(gè)月后揣炕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡东跪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年畸陡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虽填。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丁恭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斋日,到底是詐尸還是另有隱情牲览,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布恶守,位于F島的核電站第献,受9級(jí)特大地震影響贡必,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜庸毫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一仔拟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧飒赃,春花似錦利花、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至刚盈,卻和暖如春羡洛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背藕漱。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工欲侮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肋联。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓威蕉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親橄仍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子韧涨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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

  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記,整理的知識(shí)點(diǎn)侮繁,也是為了防止忘記虑粥,尊重勞動(dòng)成果,轉(zhuǎn)載注明出處哦宪哩!如果你也喜歡娩贷,那...
    波波波先森閱讀 11,244評(píng)論 4 56
  • 單任務(wù) 單任務(wù)的特點(diǎn)是排隊(duì)執(zhí)行,也就是同步锁孟,就像再cmd輸入一條命令后彬祖,必須等待這條命令執(zhí)行完才可以執(zhí)行下一條命令...
    Steven1997閱讀 1,174評(píng)論 0 6
  • 進(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,091評(píng)論 0 23
  • 供需對(duì)接平臺(tái)指的是連接供給方和需求方的平臺(tái),連接的是供給方和需求方的雙邊市場(chǎng)品抽,解決的是已經(jīng)存在但是因?yàn)榻灰壮?..
    洋氣貓閱讀 1,384評(píng)論 0 0
  • 今天上午給雅閣做保養(yǎng)单料,檢查故障燈亮较锡。猶豫之前來過只搁,給客戶說好問題報(bào)好價(jià)格队伟,客戶同意維修。說好取車時(shí)間,合理安排赘方!
    d005a7da9b80閱讀 133評(píng)論 0 0