原因:
有一句話說的好馏臭,在單核的環(huán)境下野蝇,并行算法的執(zhí)行效率差與串行計算;原因就在于對程序上鎖與下鎖需要消耗CPU資源并由CPU進行調度括儒,同時绕沈,鎖沖突也會影響效率。所以帮寻,在多核時代乍狐,即使并行計算大于串行,但鎖設計的好壞大大影響程序的執(zhí)行效率固逗。
措施:
減少上鎖時間:即將synchronized的從修飾方法到修飾臨界代碼塊浅蚪。從而達到降低鎖沖突的可能性藕帜,進而提高系統(tǒng)的并發(fā)能力。
減少鎖粒度:感覺與減少上鎖時間大差不差惜傲。其中講到了ConcurrentHashMap的安全實現(xiàn)機制:其中就是對put與get方法上鎖洽故,如果我們自己寫一個線程安全hashmap,會用synchronized或者重入鎖對put盗誊、set方法上鎖时甚,而Collections.SychronaziedMap(new HashMap)也是這么做的,但我們討論的是更高效的ConcurrentHashMap浊伙,而它并不是完全上鎖撞秋,而是在put時,首先比較hashcode嚣鄙,之后上鎖吻贿,因為對于兩個put線程,若hash表中沒有沖突哑子,則及時兩個線程誰先存入舅列,都不會影響后一個的put,而若hashcode相同卧蜓,則會有影響帐要。所以,可以將put操作分成16個段弥奸,這樣就可以最多有16個線程同時完成插入操作榨惠。
然而,這種操作也有一定的弊端:即在進行size操作時盛霎,不如直接上鎖來的效率高赠橙,具體細節(jié)不祥。
讀寫分離代替獨占鎖:上一章已經說過
鎖分離:指定義相同類型但不同名字的鎖愤炸,這樣就可以減少鎖沖突期揪。比如:在LinkedBlockingQueue中,take與put方法本是互不影響的规个,僅僅是兩個put線程不能同時凤薛、兩個take線程不能同時,而take與put無關緊要诞仓。一般的設計會定義一個ReentrantLock 對所有操作一改.lockInterruptibly()缤苫,而考慮到上述特性,定義不同鎖:takelock與putlock墅拭,可以大大減少鎖沖突活玲。
鎖粗話:合并鎖
Java虛擬機對鎖優(yōu)化的措施:鎖偏向、輕量級鎖帜矾、自旋鎖翼虫、鎖消除等,程序員可以根據(jù)不同鎖的定義以及使用場景動態(tài)的配置jvm參數(shù)屡萤,從而設置指定鎖珍剑。
人手一只筆:ThreadLocal 表示為每一個線程定義一個自己獨有的資源。
解決死鎖的方式:重入鎖的中斷與限時等待死陆。