相對(duì)于上一節(jié)中使用XXX.class粗粒度的鎖,可以使用細(xì)粒度鎖提升性能。
首先轉(zhuǎn)賬業(yè)務(wù)的資源:轉(zhuǎn)出賬戶,轉(zhuǎn)入賬戶。需要分別對(duì)兩個(gè)賬戶加鎖。


細(xì)粒度鎖提升了性能,但是存在死鎖問題:比如A、B兩個(gè)賬戶,線程1從A向B轉(zhuǎn)賬,線程2從B向A轉(zhuǎn)賬,線程1獲得A的鎖,等待B鎖;線程2獲得B鎖,等待A鎖,陷入死鎖。
出現(xiàn)死鎖滿足的四個(gè)條件:
1.互斥,共享資源 X 和 Y 只能被一個(gè)線程占用;
2.占有且等待,線程 T1 已經(jīng)取得共享資源 X,在等待共享資源 Y 的時(shí)候,不釋放共享資源 X;
3.不可搶占,其他線程不能強(qiáng)行搶占線程 T1 占有的資源;
4.循環(huán)等待,線程 T1 等待線程 T2 占有的資源,線程 T2 等待線程 T1 占有的資源,就是循環(huán)等待。
解決死鎖的方式:
1.破壞互斥性。使用鎖的目的是為了互斥,無法破壞。
2.破壞占有并等待:一次性申請(qǐng)所有的資源。這個(gè)例子里,線程所使用的資源是轉(zhuǎn)出賬戶和轉(zhuǎn)入賬戶。一次性獲取兩者的資源。引入一個(gè)管理單例對(duì)象,負(fù)責(zé)分配和收回資源。


3.破壞不可搶占條件:java中的synchronized并不能破壞這一條,無法自己釋放鎖。但是Lock類是可以的
4.。破壞循環(huán)等待:給資源排好順序,按順序分配資源。

本節(jié)問題:破壞占用且等待條件,我們也是鎖了所有的賬戶,而且還是用了死循環(huán) while(!actr.apply(this, target));這個(gè)方法,那它比 synchronized(Account.class) 有沒有性能優(yōu)勢(shì)呢?
問題回答:synchronized(Account.class)鎖住的是所有對(duì)象,導(dǎo)致只能串行進(jìn)行;使用單例管理的方式,只鎖住操作中涉及的對(duì)象,對(duì)其他對(duì)象沒有影響。