七雌隅、多線程

一、線程概述

線程是在程序中獨(dú)立并發(fā)的執(zhí)行流缸沃,相比于進(jìn)程恰起,線程具有更高的性能,多個(gè)線程可以共享一個(gè)進(jìn)程虛擬空間和泌,線程之間共享內(nèi)存非常方便村缸,可以擁有很高的并發(fā)。

二武氓、線程的創(chuàng)建和啟動(dòng)

2.1 繼承Thread類創(chuàng)建線程類

通過繼承Thread類來創(chuàng)建啟動(dòng)多線程的步驟如下:
(1)定義Thread的子類梯皿,重寫run方法
(2)創(chuàng)建Thread子類的實(shí)例
(3)通過start來啟動(dòng)線程
Thread.currentThread()可以返回當(dāng)前正在執(zhí)行的線程對(duì)象
getName()可以返回線程的名字

public class FirstThread extends Thread{
    public void run()
    {...}
}
new FirstThread().start();

2.2 實(shí)現(xiàn)Runnable接口創(chuàng)建線程類

通過Runnable接口來創(chuàng)建并啟動(dòng)多線程的步驟如下:
(1)定義Runnable的實(shí)現(xiàn)類,并且重寫run方法
(2)創(chuàng)建Runnable實(shí)現(xiàn)類的實(shí)例县恕,并且以此實(shí)例作為Thread的target來創(chuàng)建Thread對(duì)象

public class SecondThread implements Runnable
{
    public void run()
    {...}
}
new Thread(st,'name').start();

采用Runnable接口的方式來創(chuàng)建的多條線程可以共享線程類的實(shí)例屬性东羹。
采用Runnable接口方式來創(chuàng)建的線程只能通過Thread.currentThread()來獲取當(dāng)前線程,而不能通過this

3 線程的生命周期

  • 新建狀態(tài):new了一個(gè)線程之后
  • 就緒狀態(tài):調(diào)用了start之后(永遠(yuǎn)不要直接調(diào)用run方法)
  • 運(yùn)行狀態(tài):線程獲得CPU忠烛,開始運(yùn)行run方法之后
  • 阻塞狀態(tài):調(diào)用sleep,調(diào)用阻塞式IO方法属提,等待通知,程序調(diào)用了suspend方法等,都會(huì)使線程進(jìn)入阻塞狀態(tài)冤议。
  • 線程死亡:run()執(zhí)行完畢斟薇,拋出未捕獲的Exception和Error,或者調(diào)用該程序的stop()方法來結(jié)束該線程。

可以通過線程的isAlive方法來判斷線程是否死亡
不要試圖對(duì)一個(gè)已經(jīng)死亡的線程調(diào)用start方法

4 控制線程

4.1 join線程

某個(gè)線程調(diào)用另一個(gè)線程的join方法以后恕酸,該線程將被阻塞堪滨,直到被join的線程執(zhí)行完畢以后為止。

  • join()
  • join(long millis)
  • join(long millis,int nanos)

4.2 后臺(tái)線程

后臺(tái)線程有個(gè)特征:如果前臺(tái)線程都死亡蕊温,則后臺(tái)線程會(huì)自動(dòng)死亡袱箱。
通過調(diào)用Thread的setDaemon(true)的時(shí)候,就可以將其設(shè)為后臺(tái)線程义矛。
可以通過isDaemon()來判斷是否是后臺(tái)線程

4.3 線程睡眠Sleep

  • Thread.sleep(long millis)
  • Thread.sleep(long millis, int nanos)

4.4 線程讓步y(tǒng)ield

yield方法不會(huì)阻塞該線程发笔,而是轉(zhuǎn)入就緒狀態(tài),讓線程調(diào)度器重新調(diào)度一次凉翻。

  • Thread.yield

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

  • Thread.setPriority(int newPriority)
    優(yōu)先級(jí)值在1~10之間了讨,也可以使用MAX_PRIORITY(10),MIN_PRIORITY(1),NORM_PRIORITY(5)

5 線程的同步

5.1同步代碼塊

synchronized(obj){ 同步代碼塊 }

5.2同步方法

public synchronized void draw(double drawAmount)

5.3釋放同步監(jiān)視器的鎖定

以下情況會(huì)釋放:

  • 代碼塊執(zhí)行完畢
  • break return
  • 拋出錯(cuò)誤或者異常
  • 程序執(zhí)行了同步監(jiān)視器對(duì)象的wait()方法

5.4 同步鎖

常用的有可重用鎖ReentrantLock,可重用的意思是說,對(duì)已經(jīng)加鎖的ReentrantLock可以再次上鎖制轰,該對(duì)象會(huì)維持一個(gè)計(jì)數(shù)器來記錄量蕊。

public class Accout
{
    private final ReetrantLock lock = new ReentrantLock();
    public void draw(double drawAmout)
    {
        lock.lock();
        try
        {
        //臨界區(qū)
        }
        finally
        {
            lock.unlock();
        }
    }
}

5.5 死鎖

當(dāng)兩個(gè)線程相互等待對(duì)方釋放同步監(jiān)視器就會(huì)發(fā)生死鎖。

6 線程通信

6.1 線程的協(xié)調(diào)運(yùn)行

Object類提供的wait(), notify(),notifyAll()三個(gè)方法艇挨,必須由同步監(jiān)視器來調(diào)用:

  • 對(duì)于使用synchronized修飾的同步方法残炮,該類的默認(rèn)實(shí)例this就是同步監(jiān)視器
  • 對(duì)于使用synchronized修飾的代碼塊,后面括號(hào)里的對(duì)象就是同步監(jiān)視器

6.2 使用條件變量進(jìn)行控制協(xié)調(diào)

如果程序不使用synchronized關(guān)鍵字來保持同步缩滨,而是直接使用Lock對(duì)象來保持同步势就,則系統(tǒng)中不存在隱式的同步監(jiān)視器對(duì)象。Java提供了一個(gè)Condition類來保持協(xié)調(diào)脉漏。

  • await()
  • signal()
  • signalAll()
public class Account
{
    private final Lock lock = new ReentrantLock();
    private final Condition cond = lock.newCondition();

####6.3 使用管道流
如果兩條線程之間需要更多的信息交互苞冯,則可以考慮使用管道流。

PipedWriter pw = null;
PipedReader pr = null;
try
{
pw = new PipedWriter();
pr = new PipedReader();
pw.connect(pr);
new WriterThread(pw).start();
new ReaderThread(pr).start();
}

###7 Callable和Future
Callable看起來像是Runnable的接口和增強(qiáng)版侧巨,call方法是其線程執(zhí)行體舅锄,但是比run()方法更強(qiáng)大:可以有返回值,可以拋出異常

class RtnThread implements Callable<Integer>
{
public Integer call(){
return i
}
}
public class CallableTest
{
public static void main(String[] args)
{
RtnThread rt = new RtnThread();
FutrueTask<Integer> task = new FutureTask<Integer>(rt);
new Thread(task,'name').start();
System.out.println(task.get());
}
}


###8 線程池
略過

###9 線程相關(guān)類
####9.1 ThreadLocal類
ThreadLocal類是線程局部變量的意思司忱,就是為每一個(gè)使用該變量的線程都提供一個(gè)變量值的副本皇忿。從而避免沖突。
ThreadLocal提供了三個(gè)public方法:
* T get()
* void remove()
* void set(T value)
>如果需要進(jìn)行多個(gè)線程之間的資源共享坦仍,就需要使用同步機(jī)制鳍烁,如果只是需要隔離多個(gè)線程之間的共享沖突,則可以使用ThreadLocal

####9.2 線程包裝不安全的集合
Java集合中介紹的ArrayList繁扎,LinkedList, HashSet, TreeSet, HashMap都是線性不安全的幔荒『觯可以使用Collections的方法來將其變成線程安全:
SynchronizedCollection/List/Map/Set/SortedMap/SortedSet

####9.3 線程安全的集合類
JDK1.5開始,java.util.concurrent包下提供了ConcurrentHashMap, ConcurrentLinkedQueue爹梁。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末右犹,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子姚垃,更是在濱河造成了極大的恐慌傀履,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莉炉,死亡現(xiàn)場離奇詭異,居然都是意外死亡碴犬,警方通過查閱死者的電腦和手機(jī)絮宁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來服协,“玉大人绍昂,你說我怎么就攤上這事〕ズ桑” “怎么了窘游?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長跳纳。 經(jīng)常有香客問我忍饰,道長,這世上最難降的妖魔是什么寺庄? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任艾蓝,我火速辦了婚禮,結(jié)果婚禮上斗塘,老公的妹妹穿的比我還像新娘赢织。我一直安慰自己,他們只是感情好馍盟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布于置。 她就那樣靜靜地躺著,像睡著了一般贞岭。 火紅的嫁衣襯著肌膚如雪八毯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天瞄桨,我揣著相機(jī)與錄音宪彩,去河邊找鬼。 笑死讲婚,一個(gè)胖子當(dāng)著我的面吹牛尿孔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼活合,長吁一口氣:“原來是場噩夢啊……” “哼雏婶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起白指,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤留晚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后告嘲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體错维,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年橄唬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赋焕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仰楚,死狀恐怖隆判,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情僧界,我是刑警寧澤侨嘀,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站捂襟,受9級(jí)特大地震影響咬腕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜葬荷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一郎汪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧闯狱,春花似錦煞赢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瘦陈,卻和暖如春凝危,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晨逝。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來泰國打工蛾默, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捉貌。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓支鸡,卻偏偏與公主長得像冬念,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牧挣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

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