一段時間沒有回顧多線程相關知識了,雖然工做中會用到一些多線程的內容,但都偏向於基礎,今天重讀多線程相關內容,發現有些東西仍是須要注意下。這些通常是面試高頻問題奧。程序員
瞭解併發的內幕是一個高級程序員不可缺乏的課程面試
注意,Java內存模型(JMM)和JVM運行時數據區不是同一個概念,還有一個概念是Java對象模型下次能夠單獨拿出來講。安全
線程對變量的全部操做都須要在工做內存中完成,不可直接操做主內存。markdown
內存間的交互操做:
Lock,Unlock 主內存
Read,Write 主內存
Load,Store 工做內存的變量
Use,Assign 工做內存的變量多線程
更多關於JMM的信息查看,多線程之Java內存模型併發
Volatile能夠說是Java虛擬機內提供的最輕量級同步機制,其只保證,可見性與有序性,不保證原子性。app
可見性:當一條線程修改了這個變量的值,新值對於其餘線程來講是能夠馬上得知的,另外兩個能夠實現可見性的關鍵字:Synchronized
和final
ide
有序性:若是再本線程內觀察,全部的操做都是有序的,若是再一個線程中觀察另一個線程,那麼全部的操做都是無序的。性能
併發不必定依賴多線程,如PHP中常見的多進程併發。Java的Thread類全部關鍵方法都是聲明爲Native的,因此Java並無本身實現線程。優化
實現線程的三種方式:使用內核線程實現,使用用戶線程實現,和使用用戶線程加更加輕量級進程實現。
缺點:各類線程操做,如建立,析構,及同步須要進行系統調用,而系統調用的代價比較高,須要在用戶態和內核態中來回切換。消耗內核資源,一個系統支持輕量級的進程數量是有限制的。
缺點:沒有內核支持,各類操做都比較複雜。如今基本棄用了。
協同式調度:好處是實現簡單,切換操做對線程本身是可知的,沒有線程同步的問題,線程把本身的事情幹完以後才進行線程切換。
缺點:若是程序編寫不穩定,那麼系統不可控制。一個進程堅持不讓出CPU執行實現,就會致使系統崩潰。
搶佔式調度(Java默認調度):每一個線程由系統來分配執行和絃,線程的切換不禁線程來決定,當一個進程出現問題,系統能夠殺掉這個進程。
注意:並非線程的優先級越高,線程就必定會優先執行,只是說優先級高的線程更可能被選擇到。
貼一張圖,好好記:
由於們有時不值得共享數據到底被鎖了多久,盲目的自旋可能致使性能的損失,JDK1.6以後,系統引入了自適應的自旋,及在一次共享數據被鎖定時,加入系統屢次得到自旋鎖,系統能夠容許線程自旋的次數更多時間更久一些。若是屢次沒有得到自旋鎖,那麼系統下次可能會省略掉自旋鎖。
鎖消除
對一些不可能存在共享數據競爭的鎖進行消除。
鎖粗化
有時候多個操做都對同一個對象加鎖,頻繁的加鎖也會影響性能,那麼系統就把鎖的同步範圍進行擴展。如StringBuffer()的多個append操做。
瞭解併發的內幕是一個高級程序員不可缺乏的課程