并發(fā)王者課-青銅01:牛刀小試-如何創(chuàng)建線程之初體驗

歡迎來到《并發(fā)王者課》降瞳,本文是該系列文章中的第1篇征讲。

從本文開始锅知,我將基于王者中的段位和場景蛛芥,從青銅商膊、黃金鉑金帕翻、磚石鸠补、星耀王者,不同的段位對應(yīng)不同的難易程度嘀掸,由淺入深逐步介紹JAVA中的并發(fā)編程紫岩,并在每周二、四睬塌、六持續(xù)更新泉蝌。

在文章的知識體系方面,主要以實踐為主揩晴,并在實踐中穿插理論知識的講解勋陪,而本文將從最簡單的線程創(chuàng)建開始。

一文狱、一個游戲場景

在本局游戲中粥鞋,將有3位玩家出場,他們分別是哪吒瞄崇、蘇烈和安其拉呻粹。根據(jù)玩家不同的角色定位,在王者峽谷中苏研,他們會有不同的游戲路線:

  • 作為戰(zhàn)士的哪吒將走上路的對抗路線等浊;
  • 法師安其拉則去鎮(zhèn)守中路;
  • 戰(zhàn)坦蘇烈則決定去下路摹蘑。

二筹燕、代碼實現(xiàn)

顯而易見,你已經(jīng)發(fā)現(xiàn)這幾個玩家肯定不是單線程衅鹿。接下來撒踪,我們將通過簡單的多線程模擬出他們的路線。當(dāng)然大渤,真實的游戲引擎中絕不會是幾個簡單的線程制妄,情況會復(fù)雜很多。

public static void main(String[] args) {
        Thread neZhaPlayer = new Thread() {
            public void run() {
                System.out.println("我是哪吒泵三,我去上路");
            }
        };
        Thread anQiLaPlayer = new Thread() {
            public void run() {
                System.out.println("我是安其拉耕捞,我去中路");
            }
        };
        Thread suLiePlayer = new Thread() {
            public void run() {
                System.out.println("我是蘇烈,我去下路");
            }
        };
        neZhaPlayer.start();
        anQiLaPlayer.start();
        suLiePlayer.start();
}

代碼的運行結(jié)果:

我是哪吒烫幕,我去上路
我是蘇烈俺抽,我去下路
我是安其拉,我去中路

Process finished with exit code 0

以上较曼,就是游戲中簡單的代碼片段磷斧。我們創(chuàng)建了3個線程表示3個玩家,并通過run()方法實現(xiàn)他們的路線動作捷犹,隨后通過start()啟動線程弛饭。它足夠簡單,然而這里有3個知識點需要你留意伏恐。

1. 創(chuàng)建線程

Thread neZhaPlayer = new Thread();

2. 執(zhí)行代碼片段

public void run() {
    System.out.println("我是哪吒孩哑,我去上路");
}

3. 啟動線程

neZhaPlayer.start();

對于我們來說,創(chuàng)建線程并不是我們的目標(biāo)翠桦,我們的目標(biāo)是運行我們期望的代碼(比如玩家的游戲路線或某個動作)横蜒,而線程只是我們實現(xiàn)這一目標(biāo)的方式。因此销凑,在編寫多線程代碼時丛晌,運行指定的代碼片段無疑是極其重要的。在Java中斗幼,我們主要有2種方式來指定:

  • 繼承Thread并重寫run方法澎蛛;
  • 實現(xiàn)Runnable接口并將其傳遞給Thread的構(gòu)造器。

三蜕窿、線程創(chuàng)建的兩種方式

1. 繼承Thread創(chuàng)建線程

在上面的示例代碼中谋逻,我們所使用的正是這種方式呆馁,只不過是匿名實現(xiàn),你也可以通過顯示繼承:

public class NeZhaPlayer extends Thread {
    public void run() {
        System.out.println("我是哪吒毁兆,我去上路");
    }
}

此外浙滤,在Java以及更高的JDK版本中,你還可以通過lambda表達式簡化代碼:

Thread anQiLaPlayer = new Thread(() -> System.out.println("我是哪吒气堕,我去上路"));

2. 實現(xiàn)Runnable接口創(chuàng)建線程

創(chuàng)建線程的第2種方法是實現(xiàn)Runnable接口纺腊。我們創(chuàng)建了NeZhaRunnable類并實現(xiàn)Runnable接口中的run方法,如下面代碼所示茎芭。

public class NeZhaRunnable implements Runnable {
    public void run() {
        System.out.println("我是哪吒揖膜,我去上路");
    }
}

Thread neZhaPlayer = new Thread(new NeZhaRunnable());
neZhaPlayer.start();

從效果上看,兩種方式創(chuàng)建出來的線程效果是一樣的梅桩。那么壹粟,我們應(yīng)該怎么選擇?

建議你使用Runnable

對于這兩種方法摘投,孰優(yōu)孰劣并沒有明確的規(guī)定煮寡。但是,從面向?qū)ο笤O(shè)計的角度來說犀呼,推薦你用第二種方式:實現(xiàn)Runnable接口幸撕。

這是因為,在面向?qū)ο笤O(shè)計中外臂,有一條約定俗成的規(guī)則坐儿,組合優(yōu)于繼承(Prefer composition over inheritance),如果沒有特別的目的需要重寫父類方法宋光,盡量不要使用繼承貌矿。在Java中所有的類都只能是單繼承,一旦繼承Thread之后將不能繼承其他類罪佳,嚴重影響類的擴展和靈活性逛漫。另外,實現(xiàn)Runnable接口也可以與后面的更高級的并發(fā)工具結(jié)合使用赘艳。

所以酌毡,相較于繼承Thread,實現(xiàn)Runnable接口可以降低代碼之間的耦合蕾管,保持更好的靈活性枷踏。關(guān)于這一原則的更多描述,你可以參考《Effective Java》掰曾。

當(dāng)然旭蠕,如果你對Thread情有獨鐘,當(dāng)我沒說。此外掏熬,在Java中我們還可以通過ThreadFactory等工具類創(chuàng)建線程佑稠,不過本質(zhì)上仍是對這兩種方法的封裝。

四孽江、注意讶坯,別踩坑番电!

線程的啟動固然簡單岗屏,然而對于一些新手來說,在啟動線程的時候漱办,一不小心就會使用run()而不是start()这刷,就像下面這樣:

Thread neZhaPlayer = new Thread(new NeZhaRunnable());
neZhaPlayer.run();

如果你這么調(diào)用的話,你仍然可以看到你期望的輸出娩井,然而這正是陷進所在暇屋!這是因為,Runnable中的run()方法并不是你所創(chuàng)建的線程調(diào)用的洞辣,而是調(diào)用你這個線程的線程調(diào)用的咐刨,也就是主線程。那為什么直接調(diào)用run()方法也能看到輸出呢扬霜?這是因為Thread中的run()會直接調(diào)用target中的run():

public void run() {
    if (target != null) {
        target.run();
    }
}

所以你看定鸟,如果你直接調(diào)用run()的話,并不會創(chuàng)建新的線程著瓶。關(guān)于這兩個方法的執(zhí)行細節(jié)联予,會在后面的線程狀態(tài)中分析,這里你要記住的就是啟動線程調(diào)用的是start()材原,而不是run()沸久。

以上就是文本的全部內(nèi)容,恭喜你又上了一顆星?

夫子的試煉

用兩種不同的方式余蟹,創(chuàng)建出兩個線程卷胯,交差打印1~100之間的奇數(shù)和偶數(shù),并斷點調(diào)試威酒。

關(guān)于作者

關(guān)注公眾號【技術(shù)八點半】窑睁,及時獲取文章更新昂拂。傳遞有品質(zhì)的技術(shù)文章汗销,記錄平凡人的成長故事,偶爾也聊聊生活和理想榴芳。早晨8:30推送作者品質(zhì)原創(chuàng)佛呻,晚上20:30推送行業(yè)深度好文裳朋。

如果本文對你有幫助,歡迎點贊關(guān)注鲤嫡、監(jiān)督送挑,我們一起從青銅到王者

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末暖眼,一起剝皮案震驚了整個濱河市惕耕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诫肠,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栋豫,死亡現(xiàn)場離奇詭異挤安,居然都是意外死亡,警方通過查閱死者的電腦和手機丧鸯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門蛤铜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丛肢,你說我怎么就攤上這事围肥。” “怎么了蜂怎?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵穆刻,是天一觀的道長。 經(jīng)常有香客問我派敷,道長蛹批,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任篮愉,我火速辦了婚禮腐芍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘试躏。我一直安慰自己猪勇,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布颠蕴。 她就那樣靜靜地躺著泣刹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪犀被。 梳的紋絲不亂的頭發(fā)上椅您,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音寡键,去河邊找鬼掀泳。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的员舵。 我是一名探鬼主播脑沿,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼马僻!你這毒婦竟也來了庄拇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤韭邓,失蹤者是張志新(化名)和其女友劉穎措近,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仍秤,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡熄诡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诗力。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡我抠,死狀恐怖苇本,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菜拓,我是刑警寧澤瓣窄,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站纳鼎,受9級特大地震影響俺夕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贱鄙,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一劝贸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逗宁,春花似錦映九、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哼拔,卻和暖如春引有,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背倦逐。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工譬正, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓导帝,卻偏偏與公主長得像守谓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子您单,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

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