我正在嘗試爲我的特定情況找到最佳解決方案。使用ReentrantLock而不是同步來提高性能
目前,我有以下類:
public class Container
private volatile Date date;
private int amount;
private final Object lock = new Object();
public void update(int amount){
int actualAmount;
if(check(date)){
//do some BULK computation to compute the actualAmount
synchronized(lock){
date = new Date();
this.amount = actualAmount;
}
}
}
private boolean check(Date date){
synchronized(lock){
//reading from the date and returning true if the date is expired
}
}
}
類代表的用戶羣共享金額的所有更新。該組可能包含100個用戶。 amount
字段可以由該組的任何用戶同時更新。
調用update(int)
包括輸入兩個同步塊,從性能角度來看這不是很好。即使沒有必要,也可能發生BULK操作將被計算兩次或更多次。實際上,假設三個線程正試圖同時訪問update()
。 check(date)
在每個線程中都返回true。它不會造成任何傷害,但操作非常繁重(更多時間爲1分鐘)。所以,如果沒有必要,甚至兩次執行它也是非常重要的。
不可能將BULK操作包裝到同步塊中,因爲它包括調用幾個外來方法。所以,我傾向於使用ReentrantLock
而不是同步。類則可以改寫爲:
public class Container
private volatile Date date;
private int amount;
private final Lock lock = new ReentrantLock();
public void update(int amount){
int actualAmount;
lock.lock();
try{
if(check(date)){
//do some BULK computation to compute the actualAmount
date = new Date();
this.amount = actualAmount;
}
} finally {
lock.unlock();
}
}
private boolean check(Date date){
//reading from the date and returning true if the date is expired
}
}
問題:是這樣使用的ReentrantLock
在這樣的情況下比顯synchronization
更有效。
爲什麼你認爲不可能使用同步塊?你的'update()'方法鎖定一個鎖,然後它執行一些操作,然後解鎖鎖。與'synchronized'塊中的某些東西有什麼不同? –
@ jameslarge因爲我不確定BULK計算是幹什麼樣的工作人員。 –
那麼?你的'update()'方法鎖定一個鎖,它會做一些事情,然後它確保在返回之前鎖將被解鎖。一個'synchronized'塊做了完全相同的事情:它鎖定一個鎖,它做了一些事情,然後它確保鎖將被解鎖。兩種情況下的「東西」無關緊要。方法void update(int amount)中的 –