Java多線程編程寫法

寫在開頭

前段時間看了些java多線程的書和博文,但是在接下來倒沒有太多用到站绪,為了防止遺忘遭铺,準備總結一篇博文記錄一下。注:此文建議復習使用崇众。

多線程的寫法

多線程的實現方式大致有如下兩種:
  1. 繼承Thread類:extend Thread 實現 run 函數
  2. 實現Runnable接口:implements Runnable 實現run函數
線程安全

通過synchronized關鍵字實現線程間共享變量的數據安全掂僵。
Thread.currentThread()可以獲取當前線程實例。

線程調度

線程等待:使用sleep函數使線程等待相應時間
線程中止:使用推出標志顷歌、使用stop(已廢棄的方法不推薦锰蓬,可能產生無法預期的后果 如:會釋放鎖讓數據不一致)、使用interrupt(軟中斷眯漩,需要在run函數中判斷isInterrupted是否已中斷)
線程暫停:suspend暫停線程 resume恢復線程芹扭,但是這種使用方式有如下兩個缺點:1-暫停線程中的同步對象加鎖后suspend會導致鎖無法釋放舱卡,其他線程饑餓等待队萤。2-暫停線程中如果有傳入對象進行數據操作,可能會造成只操作一半舍杜,數據不同步。
另外既绩,yield方法也可以將線程暫停由其他的線程獲取CPU資源。
線程優(yōu)先級:setPriority可以設置線程優(yōu)先級私杜,線程優(yōu)先級具有繼承性救欧、規(guī)則性及隨機性。

多線程對象及并發(fā)訪問

實例變量非線程安全:多個線程共享一個實例變量時可能會出現非線程安全寄猩,可以給變量或變量方法加同步鎖(synchronized)
Synchronized不僅可以給方法加鎖也可以單獨給語句塊加鎖來提升線程運行效率骑疆。

synchronized(this){
   //coding
}

synchronized同步代碼塊會將括號中的對象作為對象監(jiān)視器箍铭,在對象相同的代碼塊會呈現同步效果椎镣,也會與該對象的同步方法呈現同步效果诈火。
需要注意的是synchronized關鍵字加在static靜態(tài)方法時,持有的Class鎖冷守,會和持有該class實例化對象鎖的代碼呈現同步效果拍摇。
synchronized以string為鎖對象的時候需要注意string常量池的問題馆截,相同值的string持有一把鎖,所以一般不建議使用string作為鎖對象蜡娶。

volatile關鍵字

volatile是線程同步的輕量實現,性能上優(yōu)于synchronized幕随,且在多線程訪問時也不會造成阻塞赘淮,volatile可以保證多線程的數據可見性枢赔,但不能保證原子性踏拜,而synchronized可以同時保證原子性和可見性低剔,另外volatile只能修飾變量。
volatile的主要使用場合是在多線程可以感知實例變量被更改了姻锁,并且可以獲得最新的值使用猜欺。

原子類

使用原子類(如:AtomicInt)可以保證其方法的原子性,但是方法和方法之間的調用不是原子的涧黄。所以還是需要在代碼中使用synchronized赋荆。

線程間通信

線程(A)可以使用持有對象鎖的wait()方法,此時會釋放該對象的鎖春宣,然后等待其他線程(B)調用該對象的notify()方法喚起此線程(A)繼續(xù)執(zhí)行之后的代碼嫉你,另外notify會隨機喚醒一個此對象wait的線程,而notifyAll則喚醒全部嚷辅。
需要注意的是notify并不會釋放鎖潦蝇,當前notify線程會繼續(xù)運行直到釋放對象鎖后深寥,被喚起的線程才會開始執(zhí)行。
wait也可以使用long型參數作為超時自動喚醒的參數惋鹅,只要當時該對象鎖未被占用,則線程自動喚醒般卑。
使用線程(A)的join方法可以使當前線程等待該線程(A)完成run之后開始執(zhí)行爽雄,另外的join也可以傳入long參數作為超時自動喚醒的參數。join的內部實現是基于wait的叹谁,所以join也會釋放鎖乘盖。
前面提到了sleep也會阻塞線程使其等待,但是不同的是sleep不會釋放鎖析苫。

線程共享變量

類ThreadLocal可以在不同線程中實現各線程隔離的共享變量衩侥,不同線程的ThreadLocal的值將保持隔離、不會污染顿乒、父子線程也不會繼承泽谨。
而類InheritableThreadLocal可以在子線程取得父線程繼承下的值吧雹,但是在繼承之后子線程與父線程仍會保持隔離。

Lock的使用

除了使用synchronized關鍵字實現同步外雄卷,Java1.5新增了ReentrantLock也可以達成同步的效果蛤售。synchronized可以使用wait/notify進行線程間通信悴能。ReentranLock也提供了通信類Condition,該類可以使用await/signal/signalAll進行等待和喚醒漠酿,另外因為ReentranLock可以創(chuàng)建多個Condition,所以也可以實現點對點多路通知宇姚。同樣的,await需要先持有對象鎖進行l(wèi)ock浑劳。
以下簡單代碼示例:

public class Service
{
     private Lock lock = new ReentrantLock();
     public Condition conditionA = lock.newCondition();
     public Condition conditionB = lock.newCondition();
     public void waitA(){
             lock.lock();
             conditionA.await();
             lock.unlock();
     }
     public void signalA(){
            lock.lock();
            conditionA.signal();
            lock.unlock();
     }
}

另外ReentrantLock有以下幾種方法:

  1. getHoldCount() 查詢當前線程鎖定的個數
  2. getQueueLength() 返回正在等待獲得該鎖定的線程數
  3. getWaitQueueLength(Condition c)返回等待該鎖定此條件(c)的線程數
  4. hasQueueThread(Thread t)查詢指定線程是否正在等待該鎖定
  5. hasWaiters(Condition c)查詢是否有線程等待該鎖定此條件(c)
    剩余不再列舉

相對于完全互斥的ReentrantLock魔熏,ReentrantReadWriteLock在某些不需要操作實例變量的方法中,可以使用讀寫鎖(readlock/writelock)來加快運行效率兵罢。讀鎖共享滓窍、寫鎖與其他鎖互斥。

定時器

Timer使用schedule進行定時操作此蜈,第一個參數一般傳入具體的timertask裆赵。其余可以接受task運行的具體日期時間Datetime或者延遲執(zhí)行時間long跺嗽,也可以傳入間隔時間period(long型),以間隔時間循環(huán)運行task植兰。
另外timertask的cancel方法可以取消當前task的運行楣导,而timer的cancel將清除所有的任務隊列畜挨。
相對于schedule,還有scheduleAtFixedRate該方法基于上次任務結束后的時間開始進行循環(huán)毡咏。

寫在結尾

多線程是一門值得深入研究和探討的核心技術务冕,以上總結寫得比較簡單淺薄,如有遺漏請不吝提醒我落恼,基本參考自《Java多線程編程核心技術》离熏,非常感謝前輩們貢獻知識。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末钻蔑,一起剝皮案震驚了整個濱河市咪笑,隨后出現的幾起案子娄涩,更是在濱河造成了極大的恐慌,老刑警劉巖扬虚,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件球恤,死亡現場離奇詭異咽斧,居然都是意外死亡,警方通過查閱死者的電腦和手機晋柱,發(fā)現死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拧额,“玉大人侥锦,你說我怎么就攤上這事德挣。” “怎么了番挺?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵襟衰,是天一觀的道長。 經常有香客問我瀑晒,道長苔悦,這世上最難降的妖魔是什么间坐? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任竹宋,我火速辦了婚禮地技,結果婚禮上,老公的妹妹穿的比我還像新娘飒硅。我一直安慰自己三娩,他們只是感情好雀监,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布会前。 她就那樣靜靜地躺著瓦宜,像睡著了一般岭妖。 火紅的嫁衣襯著肌膚如雪临庇。 梳的紋絲不亂的頭發(fā)上反璃,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音假夺,去河邊找鬼淮蜈。 笑死,一個胖子當著我的面吹牛侄泽,可吹牛的內容都是我干的礁芦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼悼尾,長吁一口氣:“原來是場噩夢啊……” “哼柿扣!你這毒婦竟也來了?” 一聲冷哼從身側響起闺魏,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤未状,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后析桥,有當地人在樹林里發(fā)現了一具尸體埋虹,經...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年崩瓤,在試婚紗的時候發(fā)現自己被綠了境输。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖偷拔,靈堂內的尸體忽然破棺而出欺旧,到底是詐尸還是另有隱情,我是刑警寧澤称龙,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布沦偎,位于F島的核電站搔驼,受9級特大地震影響,放射性物質發(fā)生泄漏泼菌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虐块。 院中可真熱鬧,春花似錦儡率、人聲如沸儿普。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篮洁。三九已至,卻和暖如春篷牌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夭苗。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工界赔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人袜腥。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓特恬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親显拜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內容