泥瓦匠聊并發(fā)編程基礎(chǔ)篇:線程與多線程必知必會(huì)

本文目錄

  • 線程與多線程
  • 線程的運(yùn)行與創(chuàng)建
  • 線程的狀態(tài)

1 線程與多線程

線程是什么?
線程(Thread)是一個(gè)對象(Object)冕茅。用來干什么?Java 線程(也稱 JVM 線程)是 Java 進(jìn)程內(nèi)允許多個(gè)同時(shí)進(jìn)行的任務(wù)汽烦。該進(jìn)程內(nèi)并發(fā)的任務(wù)成為線程(Thread)瑰煎,一個(gè)進(jìn)程里至少一個(gè)線程。

Java 程序采用多線程方式來支持大量的并發(fā)請求處理技肩,程序如果在多線程方式執(zhí)行下且轨,其復(fù)雜度遠(yuǎn)高于單線程串行執(zhí)行。那么多線程:指的是這個(gè)程序(一個(gè)進(jìn)程)運(yùn)行時(shí)產(chǎn)生了不止一個(gè)線程。

為啥使用多線程旋奢?

  • 適合多核處理器泳挥。一個(gè)線程運(yùn)行在一個(gè)處理器核心上,那么多線程可以分配到多個(gè)處理器核心上至朗,更好地利用多核處理器屉符。
  • 防止阻塞。將數(shù)據(jù)一致性不強(qiáng)的操作使用多線程技術(shù)(或者消息隊(duì)列)加快代碼邏輯處理锹引,縮短響應(yīng)時(shí)間矗钟。

聊到多線程,多半會(huì)聊并發(fā)與并行嫌变,咋理解并區(qū)分這兩個(gè)的區(qū)別呢吨艇?

  • 類似單個(gè) CPU ,通過 CPU 調(diào)度算法等初澎,處理多個(gè)任務(wù)的能力秸应,叫并發(fā)
  • 類似多個(gè) CPU ,同時(shí)并且處理相同多個(gè)任務(wù)的能力碑宴,叫做并行

2 線程的運(yùn)行與創(chuàng)建

2.1 線程的創(chuàng)建

Java 創(chuàng)建線程對象有兩種方法:

  • 繼承 Thread 類創(chuàng)建線程對象
  • 實(shí)現(xiàn) Runnable 接口類創(chuàng)建線程對象

新建 MyThread 對象软啼,代碼如下:

/**
 * 繼承 Thread 類創(chuàng)建線程對象
 * @author Jeff Lee @ bysocket.com
 * @since 2018年01月27日21:03:02
 */
public class MyThread extends Thread {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThread 的線程對象正在執(zhí)行任務(wù)");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            MyThread thread = new MyThread();
            thread.start();

            System.out.println("MyThread 的線程對象 " + thread.getId());
        }
    }
}

MyThread 類繼承了 Thread 對象,并重寫(Override)了 run 方法延柠,實(shí)現(xiàn)線程里面的邏輯祸挪。main 函數(shù)是使用 for 語句,循環(huán)創(chuàng)建了 10 個(gè)線程贞间,調(diào)用 start 方法啟動(dòng)線程贿条,最后打印當(dāng)前線程對象的 ID。

run 方法和 start 方法的區(qū)別是什么呢增热?
run 方法就是跑的意思整以,線程啟動(dòng)后,會(huì)調(diào)用 run 方法峻仇。
start 方法就是啟動(dòng)的意思公黑,就是啟動(dòng)新線程實(shí)例。啟動(dòng)線程后摄咆,才會(huì)調(diào)線程的 run 方法凡蚜。

執(zhí)行 main 方法后,控制臺(tái)打印如下:

MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 10
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 11
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 12
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 13
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 14
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 15
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 16
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 17
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 18
MyThread 的線程對象正在執(zhí)行任務(wù)
MyThread 的線程對象 19

可見吭从,線程的 ID 是線程唯一標(biāo)識(shí)符朝蜘,每個(gè)線程 ID 都是不一樣的。

start 方法和 run 方法的關(guān)系如圖所示:


同理涩金,實(shí)現(xiàn) Runnable 接口類創(chuàng)建線程對象也很簡單谱醇,只是不同的形式暇仲。新建 MyThreadBrother 代碼如下:

/**
 * 實(shí)現(xiàn) Runnable 接口類創(chuàng)建線程對象
 * @author Jeff Lee @ bysocket.com
 * @since 2018年01月27日21:22:57
 */
public class MyThreadBrother implements Runnable {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThreadBrother 的線程對象正在執(zhí)行任務(wù)");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new MyThreadBrother());
            thread.start();

            System.out.println("MyThreadBrother 的線程對象 " + thread.getId());
        }
    }
}

具體代碼:「java-concurrency-core-learning」
https://github.com/JeffLi1993/java-concurrency-core-learning

2.1 線程的運(yùn)行

在運(yùn)行上面兩個(gè)小 demo 后,JVM 執(zhí)行了 main 函數(shù)線程枣抱,然后在主線程中執(zhí)行創(chuàng)建了新的線程熔吗。正常情況下,所有線程執(zhí)行到運(yùn)行結(jié)束為止佳晶。除非某個(gè)線程中調(diào)用了 System.exit(1) 則被終止桅狠。

在實(shí)際開發(fā)中,一個(gè)請求到響應(yīng)式是一個(gè)線程轿秧。但在這個(gè)線程中可以使用線程池創(chuàng)建新的線程中跌,去執(zhí)行任務(wù)。

3 線程的狀態(tài)

新建 MyThreadInfo 類菇篡,打印線程對象屬性漩符,代碼如下:

/**
 * 線程實(shí)例對象的屬性值
 * @author Jeff Lee @ bysocket.com
 * @since 2018年01月27日21:24:40
 */
public class MyThreadInfo extends Thread {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThreadInfo 的線程實(shí)例正在執(zhí)行任務(wù)");
//        System.exit(1);
    }

    public static void main(String[] args) {
        MyThreadInfo thread = new MyThreadInfo();
        thread.start();

        System.out.print("MyThreadInfo 的線程對象 \n"
                + "線程唯一標(biāo)識(shí)符:" + thread.getId() + "\n"
                + "線程名稱:" + thread.getName() + "\n"
                + "線程狀態(tài):" + thread.getState() + "\n"
                + "線程優(yōu)先級(jí):" + thread.getPriority());
    }
}

執(zhí)行代碼打印如下:

MyThreadInfo 的線程實(shí)例正在執(zhí)行任務(wù)
MyThreadInfo 的線程對象 
線程唯一標(biāo)識(shí)符:10
線程名稱:Thread-0
線程狀態(tài):NEW
線程優(yōu)先級(jí):5

線程是一個(gè)對象,它有唯一標(biāo)識(shí)符 ID驱还、名稱嗜暴、狀態(tài)、優(yōu)先級(jí)等屬性议蟆。線程只能修改其優(yōu)先級(jí)和名稱等屬性 闷沥,無法修改 ID 、狀態(tài)咐容。ID 是 JVM 分配的舆逃,名字默認(rèn)也為 Thread-XX,XX是一組數(shù)字戳粒。線程初始狀態(tài)為 NEW路狮。

線程優(yōu)先級(jí)的范圍是 1 到 10 ,其中 1 是最低優(yōu)先級(jí)蔚约,10 是最高優(yōu)先級(jí)奄妨。不推薦改變線程的優(yōu)先級(jí),如果業(yè)務(wù)需要苹祟,自然可以修改線程優(yōu)先級(jí)到最高砸抛,或者最低。

線程的狀態(tài)實(shí)現(xiàn)通過 Thread.State 常量類實(shí)現(xiàn)苔咪,有 6 種線程狀態(tài):new(新建)锰悼、runnnable(可運(yùn)行)柳骄、blocked(阻塞)团赏、waiting(等待)、time waiting (定時(shí)等待)和 terminated(終止)耐薯。狀態(tài)轉(zhuǎn)換圖如下:

線程狀態(tài)流程大致如下:

  • 線程創(chuàng)建后舔清,進(jìn)入 new 狀態(tài)
  • 調(diào)用 start 或者 run 方法丝里,進(jìn)入 runnable 狀態(tài)
  • JVM 按照線程優(yōu)先級(jí)及時(shí)間分片等執(zhí)行 runnable 狀態(tài)的線程。開始執(zhí)行時(shí)体谒,進(jìn)入 running 狀態(tài)
  • 如果線程執(zhí)行 sleep杯聚、wait、join抒痒,或者進(jìn)入 IO 阻塞等幌绍。進(jìn)入 wait 或者 blocked 狀態(tài)
  • 線程執(zhí)行完畢后,線程被線程隊(duì)列移除故响。最后為 terminated 狀態(tài)傀广。

4 小結(jié)

本文介紹了線程與多線程的基礎(chǔ)篇,包括了線程啟動(dòng)及線程狀態(tài)等彩届。下一篇我們聊下線程的具體操作伪冰。包括中斷、終止等

具體代碼:「java-concurrency-core-learning」
https://github.com/JeffLi1993/java-concurrency-core-learning

參考:
《Java并發(fā)編程的藝術(shù)》
《Java 7 并發(fā)編程實(shí)戰(zhàn)手冊》
《圖解 Java 多線程設(shè)計(jì)模式》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末樟蠕,一起剝皮案震驚了整個(gè)濱河市贮聂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寨辩,老刑警劉巖吓懈,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捣染,居然都是意外死亡骄瓣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門耍攘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榕栏,“玉大人,你說我怎么就攤上這事蕾各“谴牛” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵式曲,是天一觀的道長妨托。 經(jīng)常有香客問我,道長吝羞,這世上最難降的妖魔是什么兰伤? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮钧排,結(jié)果婚禮上敦腔,老公的妹妹穿的比我還像新娘。我一直安慰自己恨溜,他們只是感情好符衔,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布找前。 她就那樣靜靜地躺著,像睡著了一般判族。 火紅的嫁衣襯著肌膚如雪躺盛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天形帮,我揣著相機(jī)與錄音槽惫,去河邊找鬼。 笑死辩撑,一個(gè)胖子當(dāng)著我的面吹牛躯枢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播槐臀,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼锄蹂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了水慨?” 一聲冷哼從身側(cè)響起得糜,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晰洒,沒想到半個(gè)月后朝抖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谍珊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年治宣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砌滞。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侮邀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贝润,到底是詐尸還是另有隱情绊茧,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布打掘,位于F島的核電站华畏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏尊蚁。R本人自食惡果不足惜亡笑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望横朋。 院中可真熱鬧仑乌,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祠够。三九已至压汪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間古瓤,已是汗流浹背止剖。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留落君,地道東北人穿香。 一個(gè)月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像绎速,于是被迫代替她去往敵國和親皮获。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

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