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