上周的面試中,被問及了幾個關于Java并發(fā)編程的問題,自己回答的都不是很系統(tǒng)和全面,可以說是“頭皮發(fā)麻”,哈哈。因此果斷購入《Java并發(fā)編程的藝術》一書,學習后的體會是要想快速上手Java并發(fā)編程,最需要掌握的是線程、線程池概念的理解和Executor框架的使用。
Tip:
實踐請見github-multiThread,不會介紹Java內存模型等更底層的內容。看看下圖的“糙漢”身上錯綜復雜的線[程],愿通過學習,能化繁為簡,[高效]的編出[高效]的多線程代碼。
基本概念
在實踐中,為了更好的利用資源提高系統(tǒng)整體的吞吐量,會選擇并發(fā)編程。但由于上下文切換和死鎖等問題,并發(fā)編程不一定能提高性能,因此如何合理的進行并發(fā)編程時本文的重點,接下來介紹關于鎖最基本的一些知識(選學)。
volatile:輕量,保證共享變量的可見性,使得多個線程對共享變量的變更都能及時獲取到。其包括兩個子過程,將當前處理器緩存行的數(shù)據(jù)寫回到系統(tǒng)內存,之后會使其他CPU里緩存了該內存地址的數(shù)據(jù)無效。
synchronized:相對重量,其包含3種形式,針對普通同步方法,鎖是當前實例對象;針對靜態(tài)同步方法,鎖是當前類的Class對象;對于同步代碼塊,鎖是Synchonize括號內配置的對象。此外,synchronize用的鎖存在ava對象頭中,編譯后會插入類似
monitorenter, monitorexit
的代碼。鎖狀態(tài):包括無鎖狀態(tài),偏向鎖狀態(tài),輕量級鎖狀態(tài),重量級鎖狀態(tài)。Tip,鎖可以升級但不能降級。
Java實現(xiàn)原子操作:可以通過鎖和循環(huán)CAS來實現(xiàn)原子操作,不過其也存在3個問題,包括ABA問題,通過版本號解決;循環(huán)時間長開銷大,通過
pause
指令減少自旋帶來的開銷;只能保證一個共享變