1:線程
(1)線程也叫輕量級進程。它擁有各自的計數(shù)器、堆棧和局部變量等屬性,并且能夠訪問共享的內(nèi)存變量。
(2)一個java程序的運行不僅僅是main()方法的運行,而是main線程和多個其他線程的同時運行。
(3)如果要設(shè)置線程的優(yōu)先級,那么需要注意:針對頻繁阻塞(休眠或者I/O操作)的線程需要設(shè)置較高的優(yōu)先級;而偏重計算(需要較多CPU時間或者偏運算)的線程則設(shè)置較低的優(yōu)先級,確保處理器不會被獨占。
(4)注意:線程優(yōu)先級不能作為程序正確性的依賴,因為操作系統(tǒng)可以完全不用理會java線程對于優(yōu)先級的設(shè)定。
博客:jstack工具使用?http://blog.csdn.net/fenglibing/article/details/6411999
(5)java線程的運行生命周期,在給定的某一個時刻,線程只能處于一個狀態(tài)。

下面是JAVA線程狀態(tài)變遷圖:

說明:
NEW狀態(tài)—一個被創(chuàng)建的線程,但是還沒有調(diào)用start方法。
BLOCKED狀態(tài)—一個線程因為等待臨界區(qū)的鎖被阻塞產(chǎn)生的狀態(tài)。(Lock或者synchronize關(guān)鍵字產(chǎn)生的狀態(tài)。)
WAITING狀態(tài)—一個線程進入了鎖,但是需要等待其他線程執(zhí)行某些操作,時間不確定。(當(dāng)wait,join,park方法調(diào)用時,進入waiting狀態(tài),前提是這個線程已經(jīng)擁有鎖啦。)
TIMED_WAITTING狀態(tài)—一個線程進入了鎖,但是需要等待其他線程執(zhí)行某些操作,時間確定。(通過sleep或者wait timeout方法進入的限期等待的狀態(tài)。)
TERMINATED狀態(tài)—退出
注意容易混淆的概念:阻塞在JUC包中LOCK接口的線程狀態(tài)卻是等待狀態(tài),因為JUC包中LOCK接口對于阻塞的實現(xiàn)均使用了LockSupport類中的相關(guān)方法。
(5)Daemon線程,當(dāng)java虛擬機中不存在非Daemon線程的時候,java虛擬機將會退出。
注意1:Daemon屬性需要在啟動線程之前設(shè)置,不能在啟動線程之后設(shè)置。
注意2:在構(gòu)建Daemon線程時,不能依靠finally塊中的內(nèi)容來確保執(zhí)行關(guān)閉或清理資源的邏輯。
2:啟動和終止線程
(1)線程的構(gòu)建記住一句話:一個新構(gòu)造的線程對象是由其parent線程來進行空間分配的,而child線程繼承了parent是否為Daemon、優(yōu)先級和加載資源的contextClassLoader以及可繼承的ThreadLocal,同時還會分配一個唯一的ID來標(biāo)識這個child線程。至此,一個能夠運行的線程對象就初始化好啦,在堆內(nèi)存中等待著運行。
(2)中斷?簡單的說:中斷好比其他線程對該線程打了招呼,其他線程通過調(diào)用該線程的interrupt()方法對其進行中斷操作。
(3)廢棄的API:suspend()暫停、resume()恢復(fù)、stop()停止,為啥廢棄呢?因為持有鎖,不釋放,可能導(dǎo)致死鎖。致命的的是也不支持中斷。
(4)如何安全的終止線程呢?一種方法:使用中斷來取消或停止任務(wù)。另一種方法:利用一個boolean變量來控制是否需要停止任務(wù)并終止該線程。
3:線程間通信
(1)一個線程一旦開始運行,就擁有自己的棧空間。
(2)volatile可以用來修飾字段(成員變量),就是告知程序任何對該變量的訪問均需要從共享內(nèi)存中獲取,而對它的改變必須同步刷新回共享內(nèi)存,它能保證所有線程對變量訪問的可見性。
(3)sychronized實現(xiàn)原理:對一個對象的監(jiān)視器(monitor)進行獲取,而這個獲取過程是排他的。也就是同一時刻只能有一個線程獲取到由synchronized所保護對象的監(jiān)視器。
對象、對象監(jiān)視器、同步隊列和執(zhí)行線程之間的關(guān)系

任意線程對Object(Object由synchronized保護)的訪問,首先要獲得Object的監(jiān)視器。如果獲取失敗,線程進入同步隊列,線程狀態(tài)變?yōu)锽LOCKED。當(dāng)訪問Object的前驅(qū)(獲得了鎖的線程)釋放了鎖,則該釋放操作喚醒阻塞在同步隊列中的線程,使其嘗試對監(jiān)視器的獲取。
(3)等待/通知機制是任意java對象都具備的,因為定義在Object里面。下面是等待/通知相關(guān)方法:

使用wait()、notify()、notifyAll()時需要注意的細(xì)節(jié):
1)使用wait()、notify()、notifyAll()時需要先調(diào)用對象加鎖。
2)調(diào)用wait()方法后,線程狀態(tài)由RUNNING變?yōu)閃AITING,并將當(dāng)前線程放置到等待隊列中。
3)notify()或notifyAll()方法調(diào)用后,等待線程依舊不會從wait()返回,需要調(diào)用notify()或notifyAll()的線程釋放鎖之后,等待線程才有機會從wait()返回。
4)notify()方法將等待隊列中的一個等待線程從等待隊列中移到同步隊列中,而notifyAll()方法則是將等待隊列中所有的線程全部移到同步隊列,被移動的線程狀態(tài)由WAITING變?yōu)锽LOCKED。
5)從wait()方法返回的前期是或得了調(diào)用對象的鎖。
(4)等待/通知的經(jīng)典范式,分別針對等待方(消費者)和通知方(生產(chǎn)者)
等待方遵循如下原則:
a:獲取對象的鎖
b:如果條件不滿足,那么調(diào)用對象的wait()方法,被通知后仍要檢查條件。
c:條件滿足則執(zhí)行對應(yīng)邏輯。
通知方遵循如下原則:
a:獲得對象的鎖。
b:改變條件
c:通知所有等待在對象上的線程。
(5)管道輸入/輸出流和普通文件的輸入/輸出流或者網(wǎng)絡(luò)輸入/輸出流不同處:它主要用于線程之間的數(shù)據(jù)傳輸,而傳輸?shù)拿浇闉閮?nèi)存。
PipedOutputStream、PipedInputStream面向字節(jié)
PipedWriter、PipedReader面向字符
(6)Thread.join():如果一個線程A執(zhí)行了thread.join()語句,表示:當(dāng)前線程A等待thread線程終止后才從thread.join()返回。這里涉及了等待/通知機制(等待前驅(qū)線程結(jié)束,接收前驅(qū)線程結(jié)束通知)
(7)ThreadLocal(線程變量)的使用。它是一個以ThreadLocal對象為鍵、任意對象為值的存儲結(jié)構(gòu)。這個結(jié)構(gòu)會被附帶在線程上,也就是說一個線程可以根據(jù)一個ThreadLocal對象查詢到綁定在這個線程上的一個值。
4:線程應(yīng)用實例
(1)等待超時模式?(使用等待超時模式來構(gòu)造一個簡單的數(shù)據(jù)庫連接池。)
(2)線程池技術(shù)?(使用線程池技術(shù)構(gòu)建一個簡單的web服務(wù)器。)