<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Calvin's Tech Space

    成于堅(jiān)忍,毀于浮躁

       :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
    線程概念
    線程:是指進(jìn)程中的一個(gè)執(zhí)行流程。
    線程與進(jìn)程的區(qū)別:每個(gè)進(jìn)程都需要操作系統(tǒng)為其分配獨(dú)立的內(nèi)存地址空間,而同一進(jìn)程中的所有線程在同一塊地址空間中工作,這些線程可以共享同一塊內(nèi)存和系統(tǒng)資源。

    如何創(chuàng)建一個(gè)線程?
    創(chuàng)建線程有兩種方式,如下:
    1、 擴(kuò)展java.lang.Thread類
    2、 實(shí)現(xiàn)Runnable接口
    Thread類代表線程類,它的兩個(gè)最主要的方法是:
    run()——包含線程運(yùn)行時(shí)所執(zhí)行的代碼
    Start()——用于啟動(dòng)線程

    一個(gè)線程被創(chuàng)建后只能被啟動(dòng)一次。第二次啟動(dòng)時(shí)將會(huì)拋出java.lang.IllegalThreadExcetpion異常

    線程間狀態(tài)的轉(zhuǎn)換
    新建狀態(tài):用new語句創(chuàng)建的線程對(duì)象處于新建狀態(tài),此時(shí)它和其它的java對(duì)象一樣,僅僅在堆中被分配了內(nèi)存
    就緒狀態(tài):當(dāng)一個(gè)線程創(chuàng)建了以后,其他的線程調(diào)用了它的start()方法,該線程就進(jìn)入了就緒狀態(tài)。處于這個(gè)狀態(tài)的線程位于可運(yùn)行池中,等待獲得CPU的使用權(quán)
    運(yùn)行狀態(tài):處于這個(gè)狀態(tài)的線程占用CPU,執(zhí)行程序的代碼
    阻塞狀態(tài):當(dāng)線程處于阻塞狀態(tài)時(shí),java虛擬機(jī)不會(huì)給線程分配CPU,直到線程重新進(jìn)入就緒狀態(tài),它才有機(jī)會(huì)轉(zhuǎn)到運(yùn)行狀態(tài)。
    阻塞狀態(tài)分為三種情況:
    1、 位于對(duì)象等待池中的阻塞狀態(tài):當(dāng)線程運(yùn)行時(shí),如果執(zhí)行了某個(gè)對(duì)象的wait()方法,java虛擬機(jī)就回把線程放到這個(gè)對(duì)象的等待池中
    2、 位于對(duì)象鎖中的阻塞狀態(tài),當(dāng)線程處于運(yùn)行狀態(tài)時(shí),試圖獲得某個(gè)對(duì)象的同步鎖時(shí),如果該對(duì)象的同步鎖已經(jīng)被其他的線程占用,JVM就會(huì)把這個(gè)線程放到這個(gè)對(duì)象的瑣池中。
    3、 其它的阻塞狀態(tài):
    • 當(dāng)前線程執(zhí)行了sleep()方法
    • 調(diào)用了其它線程的join()方法
    • 發(fā)出了I/O請(qǐng)求時(shí)
    死亡狀態(tài):當(dāng)線程退出了run()方法,就進(jìn)入了死亡狀態(tài),該線程結(jié)束了生命周期。
    或者正常退出
    或者遇到異常退出

    Thread類的isAlive()方法判斷一個(gè)線程是否活著,當(dāng)線程處于死亡狀態(tài)或者新建狀態(tài)時(shí),該方法返回false,在其余的狀態(tài)下,該方法返回true.

    線程調(diào)度
    線程調(diào)度模型:分時(shí)調(diào)度模型和搶占式調(diào)度模型
    JVM采用搶占式調(diào)度模型。
    所謂的多線程的并發(fā)運(yùn)行,其實(shí)是指宏觀上看,各個(gè)線程輪流獲得CPU的使用權(quán),分別執(zhí)行各自的任務(wù)。
    (線程的調(diào)度不是跨平臺(tái),它不僅取決于java虛擬機(jī),它還依賴于操作系統(tǒng))

    如果希望明確地讓一個(gè)線程給另外一個(gè)線程運(yùn)行的機(jī)會(huì),可以采取以下的辦法之一
    1、 調(diào)整各個(gè)線程的優(yōu)先級(jí)
    2、 讓處于運(yùn)行狀態(tài)的線程調(diào)用Thread.sleep()方法
    3、 讓處于運(yùn)行狀態(tài)的線程調(diào)用Thread.yield()方法
    4、 讓處于運(yùn)行狀態(tài)的線程調(diào)用另一個(gè)線程的join()方法

    調(diào)整各個(gè)線程的優(yōu)先級(jí)
    Thread類的setPriority(int)和getPriority()方法分別用來設(shè)置優(yōu)先級(jí)和讀取優(yōu)先級(jí)。
    如果希望程序能夠移值到各個(gè)操作系統(tǒng)中,應(yīng)該確保在設(shè)置線程的優(yōu)先級(jí)時(shí),只使用MAX_PRIORITY、NORM_PRIORITY、MIN_PRIORITY這3個(gè)優(yōu)先級(jí)。

    線程睡眠:當(dāng)線程在運(yùn)行中執(zhí)行了sleep()方法時(shí),它就會(huì)放棄CPU,轉(zhuǎn)到阻塞狀態(tài)。
    線程讓步:當(dāng)線程在運(yùn)行中執(zhí)行了Thread類的yield()靜態(tài)方法時(shí),如果此時(shí)具有相同優(yōu)先級(jí)的其它線程處于就緒狀態(tài),那么yield()方法將把當(dāng)前運(yùn)行的線程放到運(yùn)行池中并使另一個(gè)線程運(yùn)行。如果沒有相同優(yōu)先級(jí)的可運(yùn)行線程,則yield()方法什么也不做。
    Sleep()方法和yield()方法都是Thread類的靜態(tài)方法,都會(huì)使當(dāng)前處于運(yùn)行狀態(tài)的線程放棄CPU,把運(yùn)行機(jī)會(huì)讓給別的線程,兩者的區(qū)別在于:
    1、sleep()方法會(huì)給其他線程運(yùn)行的機(jī)會(huì),而不考慮其他線程的優(yōu)先級(jí),因此會(huì)給較低線程一個(gè)運(yùn)行的機(jī)會(huì);yield()方法只會(huì)給相同優(yōu)先級(jí)或者更高優(yōu)先級(jí)的線程一個(gè)運(yùn)行的機(jī)會(huì)。
    2、當(dāng)線程執(zhí)行了sleep(long millis)方法后,將轉(zhuǎn)到阻塞狀態(tài),參數(shù)millis指定睡眠時(shí)間;當(dāng)線程執(zhí)行了yield()方法后,將轉(zhuǎn)到就緒狀態(tài)。
    3、sleep()方法聲明拋出InterruptedException異常,而yield()方法沒有聲明拋出任何異常
    4、sleep()方法比yield()方法具有更好的移植性

    等待其它線程的結(jié)束:join()
    當(dāng)前運(yùn)行的線程可以調(diào)用另一個(gè)線程的 join()方法,當(dāng)前運(yùn)行的線程將轉(zhuǎn)到阻塞狀態(tài),直到另一個(gè)線程運(yùn)行結(jié)束,它才恢復(fù)運(yùn)行。

    定時(shí)器Timer:在JDK的java.util包中提供了一個(gè)實(shí)用類Timer, 它能夠定時(shí)執(zhí)行特定的任務(wù)。

    線程的同步
    原子操作:根據(jù)Java規(guī)范,對(duì)于基本類型的賦值或者返回值操作,是原子操作。但這里的基本數(shù)據(jù)類型不包括long和double, 因?yàn)镴VM看到的基本存儲(chǔ)單位是32位,而long 和double都要用64位來表示。所以無法在一個(gè)時(shí)鐘周期內(nèi)完成。

    自增操作(++)不是原子操作,因?yàn)樗婕暗揭淮巫x和一次寫。

    原子操作:由一組相關(guān)的操作完成,這些操作可能會(huì)操縱與其它的線程共享的資源,為了保證得到正確的運(yùn)算結(jié)果,一個(gè)線程在執(zhí)行原子操作其間,應(yīng)該采取其他的措施使得其他的線程不能操縱共享資源。

    同步代碼塊:為了保證每個(gè)線程能夠正常執(zhí)行原子操作,Java引入了同步機(jī)制,具體的做法是在代表原子操作的程序代碼前加上synchronized標(biāo)記,這樣的代碼被稱為同步代碼塊。

    同步鎖:每個(gè)JAVA對(duì)象都有且只有一個(gè)同步鎖,在任何時(shí)刻,最多只允許一個(gè)線程擁有這把鎖。

    當(dāng)一個(gè)線程試圖訪問帶有synchronized(this)標(biāo)記的代碼塊時(shí),必須獲得 this關(guān)鍵字引用的對(duì)象的鎖,在以下的兩種情況下,本線程有著不同的命運(yùn)。
    1、 假如這個(gè)鎖已經(jīng)被其它的線程占用,JVM就會(huì)把這個(gè)線程放到本對(duì)象的鎖池中。本線程進(jìn)入阻塞狀態(tài)。鎖池中可能有很多的線程,等到其他的線程釋放了鎖,JVM就會(huì)從鎖池中隨機(jī)取出一個(gè)線程,使這個(gè)線程擁有鎖,并且轉(zhuǎn)到就緒狀態(tài)。
    2、 假如這個(gè)鎖沒有被其他線程占用,本線程會(huì)獲得這把鎖,開始執(zhí)行同步代碼塊。
    (一般情況下在執(zhí)行同步代碼塊時(shí)不會(huì)釋放同步鎖,但也有特殊情況會(huì)釋放對(duì)象鎖
    如在執(zhí)行同步代碼塊時(shí),遇到異常而導(dǎo)致線程終止,鎖會(huì)被釋放;在執(zhí)行代碼塊時(shí),執(zhí)行了鎖所屬對(duì)象的wait()方法,這個(gè)線程會(huì)釋放對(duì)象鎖,進(jìn)入對(duì)象的等待池中)

    線程同步的特征:
    1、 如果一個(gè)同步代碼塊和非同步代碼塊同時(shí)操作共享資源,仍然會(huì)造成對(duì)共享資源的競爭。因?yàn)楫?dāng)一個(gè)線程執(zhí)行一個(gè)對(duì)象的同步代碼塊時(shí),其他的線程仍然可以執(zhí)行對(duì) 象的非同步代碼塊。(所謂的線程之間保持同步,是指不同的線程在執(zhí)行同一個(gè)對(duì)象的同步代碼塊時(shí),因?yàn)橐@得對(duì)象的同步鎖而互相牽制)
    2、 每個(gè)對(duì)象都有唯一的同步鎖
    3、 在靜態(tài)方法前面可以使用synchronized修飾符。
    4、 當(dāng)一個(gè)線程開始執(zhí)行同步代碼塊時(shí),并不意味著必須以不間斷的方式運(yùn)行,進(jìn)入同步代碼塊的線程可以執(zhí)行Thread.sleep()或者執(zhí)行Thread.yield()方法,此時(shí)它并不釋放對(duì)象鎖,只是把運(yùn)行的機(jī)會(huì)讓給其他的線程。
    5、 Synchronized聲明不會(huì)被繼承,如果一個(gè)用synchronized修飾的方法被子類覆蓋,那么子類中這個(gè)方法不在保持同步,除非用synchronized修飾。

    線程安全的類:
    1、 這個(gè)類的對(duì)象可以同時(shí)被多個(gè)線程安全的訪問。
    2、 每個(gè)線程都能正常的執(zhí)行原子操作,得到正確的結(jié)果。
    3、 在每個(gè)線程的原子操作都完成后,對(duì)象處于邏輯上合理的狀態(tài)。

    釋放對(duì)象的鎖:
    1、 執(zhí)行完同步代碼塊就會(huì)釋放對(duì)象的鎖
    2、 在執(zhí)行同步代碼塊的過程中,遇到異常而導(dǎo)致線程終止,鎖也會(huì)被釋放
    3、 在執(zhí)行同步代碼塊的過程中,執(zhí)行了鎖所屬對(duì)象的wait()方法,這個(gè)線程會(huì)釋放對(duì)象鎖,進(jìn)入對(duì)象的等待池。

    死鎖
    當(dāng)一個(gè)線程等待由另一個(gè)線程持有的鎖,而后者正在等待已被第一個(gè)線程持有的鎖時(shí),就會(huì)發(fā)生死鎖。JVM不監(jiān)測也不試圖避免這種情況,因此保證不發(fā)生死鎖就成了程序員的責(zé)任。

    如何避免死鎖
    一個(gè)通用的經(jīng)驗(yàn)法則是:當(dāng)幾個(gè)線程都要訪問共享資源A、B、C 時(shí),保證每個(gè)線程都按照同樣的順序去訪問他們。

    線程通信
    Java.lang.Object類中提供了兩個(gè)用于線程通信的方法
    1、 wait():執(zhí)行了該方法的線程釋放對(duì)象的鎖,JVM會(huì)把該線程放到對(duì)象的等待池中。該線程等待其它線程喚醒
    2、 notify():執(zhí)行該方法的線程喚醒在對(duì)象的等待池中等待的一個(gè)線程,JVM從對(duì)象的等待池中隨機(jī)選擇一個(gè)線程,把它轉(zhuǎn)到對(duì)象的鎖池中。
    posted on 2010-10-29 15:23 calvin 閱讀(266) 評(píng)論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 免费一级毛suv好看的国产网站 | 免费高清在线爱做视频| 亚洲综合图片小说区热久久| 久久国产乱子精品免费女| 亚洲欧洲美洲无码精品VA| 韩国免费a级作爱片无码| 亚洲精品一品区二品区三品区| 国产成人无码精品久久久久免费| 免费在线观看理论片| 免费人成视频在线播放| 亚洲精品国产综合久久一线| 香蕉免费在线视频| 亚洲国产精品嫩草影院在线观看| 久久午夜无码免费| 丰满人妻一区二区三区免费视频| 亚洲中文字幕丝袜制服一区| 99re6在线精品免费观看| 午夜亚洲国产理论秋霞| 国产91色综合久久免费分享| 国产亚洲国产bv网站在线| 中文字幕一区二区免费| 亚洲AV无码成人专区片在线观看 | 国产免费av片在线看| 亚洲欧美日韩中文二区| 亚洲国产精品无码久久久久久曰 | 国产99久久久国产精免费| 亚洲电影一区二区| 成熟女人特级毛片www免费| 免费无码午夜福利片| 久久亚洲国产成人亚| 啦啦啦中文在线观看电视剧免费版 | 我的小后妈韩剧在线看免费高清版| 亚洲大成色www永久网址| 亚洲国产小视频精品久久久三级 | 黄页网站免费在线观看| 免费看一级毛片在线观看精品视频| 久久久久久亚洲精品| 国产婷婷高清在线观看免费| 182tv免费视频在线观看| 亚洲一区二区三区国产精华液| 久久国产成人精品国产成人亚洲|