寫在前面:
多執行緒并發等知識點涉及面廣,延伸度大,理論加原始碼的方式整理關于執行緒的部分基礎知識,其他更多的更深的知識會在后面一一學習和整理,先學習基礎,再延伸,
目錄
一、執行緒與行程
二、執行緒實作
繼承 Thread
實作Runnable
實作Callable&Future
三、執行緒生命周期及狀態轉換
新建
可運行
運行
阻塞
等待
超時等待
終止
四、常見操作方法分析
Thread.sleep(long millis)
Thread.yield()
t.join()/t.join(long millis)
obj.wait()
obj.notify()
五、執行緒池
六、常見并發容器
ConcurrentHashMap
其他并發容器
佇列
七、執行緒安全
一、執行緒與行程
行程是指一個記憶體中運行的應用程式,每個行程都有自己獨立的一塊記憶體空間,是系統進行資源分配和調度的一個獨立單位,是程式運行的最小單元,
執行緒是指行程中的一個執行流程,沒有自己的記憶體空間,是cpu運行和分派的最小單元,
在Java中,每次程式運行至少啟動2個執行緒:一個是main執行緒,一個是垃圾收集執行緒,因為每當使用java命令執行一個類的時候,實際上都會啟動一個JVM,每一個JVM實際上就是在作業系統中啟動了一個行程,
二、執行緒實作
繼承 Thread
由于java是單繼承,所以基本不用這種實作方式
實作Runnable
介面,重寫run()
實作Callable&Future
待續
三、執行緒生命周期及狀態轉換

新建
new 【來到體育場 】
可運行
runnable 【進入備跑區】
執行緒物件創建后,其他執行緒呼叫了該執行緒的start方法,進入執行緒池等待被調度選中,獲取cpu使用權,當前執行緒sleep()方法結束,其他執行緒join()結束,等待用戶輸入完畢,某個執行緒拿到物件鎖,這些執行緒也將進入可運行狀態,當前執行緒時間片用完了,呼叫當前執行緒的yield()方法,當前執行緒進入可運行狀態,鎖池里的執行緒拿到物件鎖后,進入可運行狀態,
運行
running 【起跑】
runnable狀態下獲得了cpu時間片(timeslice),執行程式,
阻塞
blocked 【停下去做點啥】
執行緒因為某些原因放棄了cpu使用權,讓出了cpu timeslice,暫停運行,直到執行緒重新進入runnable,
所謂阻塞狀態是正在運行的執行緒沒有運行結束,暫時讓出CPU,這時其他處于就緒狀態的執行緒就可以獲得CPU時間,進入運行狀態,
blocked分三種:
等待阻塞 wait()方法執行,進入等待佇列(waitting queue)
同步阻塞 running的執行緒在獲取物件的同步鎖時,若該同步鎖被別的執行緒占用,JVM會把它放到鎖池(lock pool)中,等拿到鎖之后才會進入可運行
其他阻塞 Thread.sleep(long ms) 睡上五分鐘,醒來再進執行緒池
t.join() 跑著跑著突然被插隊,你不得不停下
發出IO請求時,jvm會把該執行緒置為阻塞狀態, 跑著跑著,你去看了看檔案,所以得停下
當 sleep()狀態超時 睡醒了
join()等待執行緒終止或者超時 插隊的人走了或掛了
或者I/O處理完畢時 檔案看完了
執行緒重新轉入可運行(runnable)狀態,
等待
waiting 【等著,別人叫再跑】
處于這種狀態的執行緒不會被分配CPU執行時間,它們要等待被顯式地喚醒,否則會處于無限期等待的狀態,
超時等待
time waiting 【等著,過了等待時間就不等了】
處于這種狀態的執行緒不會被分配CPU執行時間,不過無須無限期等待被其他執行緒顯示地喚醒,在達到一定時間后它們會自動喚醒,
終止
terminated 【跑完或者意外退場】
run()、main()執行結束,或因例外退出run()方法,結束該執行緒生命周期,死亡的不可復生,
四、常見操作方法分析
Thread.sleep(long millis)
一定是當前執行緒呼叫此方法,當前執行緒進入阻塞,但不釋放物件鎖,millis后執行緒自動蘇醒進入可運行狀態,作用:給其它執行緒執行機會的最佳方式,
Thread.yield()
一定是當前執行緒呼叫此方法,當前執行緒放棄獲取的cpu時間片,由運行狀態變會可運行狀態,讓OS再次選擇執行緒,作用:讓相同優先級的執行緒輪流執行,但并不保證一定會輪流執行,實際中無法保證yield()達到讓步目的,因為讓步的執行緒還有可能被執行緒調度程式再次選中,Thread.yield()不會導致阻塞,
t.join()/t.join(long millis)
當前執行緒里呼叫其它執行緒1的join方法,當前執行緒阻塞,但不釋放物件鎖,直到執行緒1執行完畢或者millis時間到,當前執行緒進入可運行狀態,
obj.wait()
當前執行緒呼叫物件的wait()方法,當前執行緒釋放物件鎖,進入等待佇列,依靠notify()/notifyAll()喚醒或者wait(long timeout)timeout時間到自動喚醒,
obj.notify()
喚醒在此物件監視器上等待的單個執行緒,選擇是任意性的,notifyAll()喚醒在此物件監視器上等待的所有執行緒,
五、執行緒池
ThreadPoolExecutor extends Executor
六、常見并發容器
ConcurrentHashMap
待續
其他并發容器
待續
佇列
同步佇列
當前執行緒想呼叫物件A的同步方法時,發現物件A的鎖被別的執行緒占有,此時當前執行緒進入同步佇列,簡言之,同步佇列里面放的都是想爭奪物件鎖的執行緒,同步佇列是在同步的環境下才有的概念,一個物件對應一個同步佇列,
鎖池佇列
鎖池里面放的都是想爭奪物件鎖的執行緒,當一個執行緒1被另外一個執行緒2喚醒時,1執行緒進入鎖池狀態,去爭奪物件鎖,
鎖池是在同步的環境下才有的概念,一個物件對應一個鎖池,
等待佇列
待續
七、執行緒安全
定義:CPU的使用權搶占和資源的共享發生了沖突
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/189954.html
標籤:其他
下一篇:單例模式的六種實作方式
