我正在尝试为我的特定情况找到最佳解决方案。使用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)中的 –