Java多線程隨筆記

參考:
1.http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html

2.http://blog.csdn.net/ghsau/article/category/1707779

本文為本人學(xué)習(xí)時(shí)記錄, **不做詳細(xì)介紹** 里面內(nèi)容都來(lái)源于網(wǎng)上,所有引用都會(huì)在頭部聲明,如有侵權(quán)還望告知,本人將即時(shí)做出修改

1.volatile:

每個(gè)線程運(yùn)行時(shí)都有一個(gè)線程棧,它保存了線程運(yùn)行時(shí)的變量,當(dāng)一個(gè)線程訪問(wèn)一個(gè)對(duì)象時(shí),首先通過(guò)對(duì)象的引用找到其對(duì)應(yīng)在堆內(nèi)存的變量值,然后把變量的具體值load到該線程的線程棧中,之后線程就和對(duì)象在堆內(nèi)存的變量值沒(méi)有關(guān)系了,而是直接修改副本變量的值,修改完成后某一時(shí)刻(線程退出前),自動(dòng)把線程變量副本的值回寫(xiě)到對(duì)象在堆中的變量。

[來(lái)源](http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html)

volatile修飾的變量,jvm虛擬機(jī)只是保證從主內(nèi)存加載到線程工作內(nèi)存的值是最新的,并不能規(guī)避并發(fā)問(wèn)題。
例如假如線程1,線程2 在進(jìn)行read,load 操作中,發(fā)現(xiàn)主內(nèi)存中count的值都是5,那么都會(huì)加載這個(gè)最新的值,在線程1堆count進(jìn)行修改之后,會(huì)write到主內(nèi)存中,主內(nèi)存中的count變量就會(huì)變?yōu)?,線程2由于已經(jīng)進(jìn)行read,load操作,在進(jìn)行運(yùn)算之后,也會(huì)更新主內(nèi)存count的變量值為6,導(dǎo)致兩個(gè)線程即使用volatile關(guān)鍵字修改之后,還是會(huì)存在并發(fā)的情況。

2.synchronized:

同一個(gè)對(duì)象的同步代碼塊(一個(gè)或多個(gè)),同一時(shí)間內(nèi)只能有一個(gè)線程訪問(wèn),其他線程的訪問(wèn)(無(wú)論是該同步代碼塊還是該對(duì)象其他同步代碼塊)都處于阻塞狀態(tài)直到先前線程訪問(wèn)結(jié)束,此時(shí),其他線程仍可以訪問(wèn)該對(duì)象的非同步代碼塊,synchronized同時(shí)修飾一個(gè)類的靜態(tài)方法和非靜態(tài)方法,線程訪問(wèn),一個(gè)獲取的是類鎖、一個(gè)是獲取的對(duì)象鎖,互不干擾,可以同時(shí)訪問(wèn),同樣一個(gè)線程可以同時(shí)獲得這兩個(gè)鎖。

  • 修飾一個(gè)代碼塊,作用的對(duì)象是調(diào)用這個(gè)代碼塊的對(duì)象
  • 修飾一個(gè)方法,作用的對(duì)象是調(diào)用這個(gè)方法的對(duì)象
  • 修飾一個(gè)靜態(tài)方法,作用的對(duì)象是這個(gè)類的所有對(duì)象
  • 修改一個(gè)類,作用的對(duì)象是這個(gè)類的所有對(duì)象

3.wait+notify+notifyAll

線程協(xié)作-生產(chǎn)者/消費(fèi)者問(wèn)題。這三個(gè)方法都是Object的方法,調(diào)用wait將釋放鎖,notify隨機(jī)喚醒一個(gè)線程,notifyAll喚醒所有線程。
在調(diào)用wait方法時(shí),都是用while判斷條件的,而不是if,在wait方法說(shuō)明中,也推薦使用while,因?yàn)樵谀承┨囟ǖ那闆r下,線程有可能被假喚醒,使用while會(huì)循環(huán)檢測(cè)更穩(wěn)妥。wait和notify方法必須工作于synchronized內(nèi)部,且這兩個(gè)方法只能由鎖對(duì)象來(lái)調(diào)用。

4.線程中斷、線程讓步、線程睡眠、線程合并、線程優(yōu)先級(jí)

  • 線程中斷

    • void interrupt()中斷線程,并不是真正停止線程執(zhí)行,只是設(shè)置狀態(tài)為true,如果線程在調(diào)用 Object 類的 wait()、wait(long) 或 wait(long, int) 方法,或者該類的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法過(guò)程中受阻,則其中斷狀態(tài)將被清除,它還將收到一個(gè) InterruptedException;
    • static boolean interrupted()判斷當(dāng)前線程是否中斷,線程的中斷狀態(tài)會(huì)由該方法清除,如果連續(xù)兩次調(diào)用該方法,則第二次調(diào)用將返回 false;
    • boolean isInterrupted()判斷線程是否中斷,線程的中斷狀態(tài)會(huì)由該方法清除,如果連續(xù)兩次調(diào)用該方法,則第二次調(diào)用將返回 false。
  • 線程讓步
    -static void yield()暫停當(dāng)前正在執(zhí)行的線程,并執(zhí)行其他線程,如果存在synchronized線程同步的話,線程讓步不會(huì)釋放鎖(監(jiān)視器對(duì)象)。

  • 線程睡眠
    -static void sleep(long millis)讓當(dāng)前線程暫停執(zhí)行millis毫秒,如果存在synchronized線程同步的話,線程讓步不會(huì)釋放鎖(監(jiān)視器對(duì)象)。
    -static void sleep(long millis, int nanos)讓當(dāng)前線程暫停執(zhí)行millis毫秒 + nanos納秒,如果存在synchronized線程同步的話,線程讓步不會(huì)釋放鎖(監(jiān)視器對(duì)象)。

  • 線程合并
    -void join()等待該線程終止;
    -void join(long millis)等待該線程終止的時(shí)間最長(zhǎng)為 millis毫秒;
    -void join(long millis, int nanos)等待該線程終止的時(shí)間最長(zhǎng)為 millis毫秒 + nanos納秒。
    所謂合并就是等待其他線程執(zhí)行完成,再執(zhí)行當(dāng)前線程

  • 線程優(yōu)先級(jí)

    • public static final int MAX_PRIORITY = 10
    • public static final int MIN_PRIORITY = 1
    • public static final int NORM_PRIORITY = 5
      默認(rèn)為NORM_PRIORITY,優(yōu)先級(jí)高的,獲取CPU調(diào)度的機(jī)會(huì)就大

5.定時(shí)任務(wù)

Timer和TimerTask,自JDK5之后,可以用ScheduledThreadPoolExecutor來(lái)替代Timer。

6.Callable、Future和FutureTask

創(chuàng)建線程的2種方式,一種是直接繼承Thread,另外一種就是實(shí)現(xiàn)Runnable接口,這兩種方式的缺點(diǎn)是:在執(zhí)行完任務(wù)后無(wú)法獲取執(zhí)行結(jié)果,從JDK5開(kāi)始,就提供了Callable和Future,通過(guò)它們可以在任務(wù)執(zhí)行完畢之后得到任務(wù)執(zhí)行結(jié)果。閱讀過(guò)Android中AsyncTask源碼的同學(xué)應(yīng)該會(huì)發(fā)現(xiàn)AsyncTask中也應(yīng)用了這兩個(gè)類。

7.鎖對(duì)象Lock

用sychronized修飾的方法或者語(yǔ)句塊在代碼執(zhí)行完之后鎖自動(dòng)釋放,而用Lock需要我們手動(dòng)釋放鎖,所以為了保證鎖最終被釋放(發(fā)生異常情況),要把互斥區(qū)放在try內(nèi),釋放鎖放在finally內(nèi)。與synchronized的區(qū)別

8.Condition

Condition中await()對(duì)應(yīng)Object#wait(),signal()對(duì)應(yīng)Object#notify(),signalAll()對(duì)應(yīng)Object#notifyAll(),Condition與Lock結(jié)合使用,通過(guò)Lock.newCondition()方法創(chuàng)建與Lock綁定的Condition實(shí)例。Lock和Condition的關(guān)系就如同 Object.wait(),Object.notify()方法和synchronized一樣,它們都可以配合使用完成對(duì)多線程協(xié)作的控制。
其他不常用的暫不記載,例如CAS、并行計(jì)算的框架Fork/Join、ThreadLocal、BlockingQueue等

技術(shù)有限,錯(cuò)誤的地方還忘大家指出
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 該文章轉(zhuǎn)自:http://blog.csdn.net/evankaka/article/details/44153...
    加來(lái)依藍(lán)閱讀 7,465評(píng)論 3 87
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 3,106評(píng)論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽(yáng)閱讀 2,594評(píng)論 1 15
  • 寫(xiě)在前面的話: 這篇博客是我從這里“轉(zhuǎn)載”的,為什么轉(zhuǎn)載兩個(gè)字加“”呢?因?yàn)檫@絕不是簡(jiǎn)單的復(fù)制粘貼,我花了五六個(gè)小...
    SmartSean閱讀 4,936評(píng)論 12 45
  • 我們終將失去一切依憑,你必須要在自己里面尋找一些永恒的東西。無(wú)論何時(shí)何地,我都愿意慈悲地注視自己。也正是因?yàn)檫@樣,...
    楚浛閱讀 1,247評(píng)論 1 3

友情鏈接更多精彩內(nèi)容