我遇到過這種情況幾次。你需要的是一個單例LockFactory,它實際上是一個鎖對象的弱引用字典。代碼應該是這樣的:
class LockFactory {
private LockFactory() {}
private LockFactory instance = null;
public static LockFactory getInstance() {
if (this.instance == null)
this.instance = new LockFactory();
return this.instance;
}
private int _last_check_size = 0;
private int _cleanup_size = 1000;
private Map<String, WeakReference> weakRefDictionary = new HashMap<String, WeakReference>();
public object getLock(String id) {
synchronized(this) {
if (!this.weakRefDictionary.containsKey(id))
this.weakRefDictionary.put(id, new WeakReference(null));
Object lock = this.weakRefDictionary.get(id).Target;
if (lock == null) {
lock = new Object();
this.weakRefDictionary.get(id).Target = lock;
}
if (this.weakRefDictionary.size() > this._last_check_size + this._cleanup_size)
this._do_cleanup();
return lock;
}
}
public void _do_cleanup() {
synchronized(this) {
Iterator<Map.Entry<String, WeakReference>> iter = this.weakRefDictionary.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,WeakReference> entry = iter.next();
if (entry.getValue().get() == null) {
iter.remove();
}
}
this._last_check_size = this.weakRefDictionary.size();
}
}
}
現在你的情況使用只是做:
public void beforeUpdated(Log log){
synchronized(LockFactory.getInstance().getLock(log.getUuid())){
query(log);
merge(log);
persist(log);
}
}
我會添加一切到單線程後臺線程池。如果速度足夠快,則不需要任何額外的鎖定。 –