[英]Will this method work thread-safe and without Deadlocks
public int saveUserToMap(User user) {
ReentrantLock lock;
if(this.userLocks.containsKey(user.getId())) {
lock = this.userLocks.get(user.getId());
} else {
lock = new ReentrantLock();
ReentrantLock check = this.userLocks.putIfAbsent(user.getId(), lock);
if(check != null)
lock = check;
}
if(lock.isLocked())
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.lock();
this.users.put(user.getId(), user);
this.usersByName.put(user.getUsername(), user);
this.usersByEmail.put(user.getEmail(), user);
lock.unlock();
lock.notify();
return user.getId();
}
嘿,我只想請Java開發人員檢查我的代碼是否是線程安全的,並且沒有死鎖,因為我想在項目中使用它。 Users,UsersByName和UsersByEmail是ConcurrentHashMap,其中String,Integer作為鍵,User對象作為Value。 UserLocks是一個帶有Integer(顯然是用戶ID作為鍵)和ReentrantLock作為值的ConcurrentHashMap。 我想同步三個HashMap。 如果有人有更好的解決方案來制作帶有三個鍵的並發地圖,最好在此處發布。 性能也很重要。
這是線程安全的。
如果userId已經在映射中,則代碼獲取鎖並使用它進行同步。 如果沒有, ConcurrentHashMap
提供同步功能,以避免爭用條件為同一id使用不同的鎖。
之后,有一段無用的代碼片段,您可以擺脫掉:
if(lock.isLocked())
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
不需要,因為同步是使用lock.lock()
。 不需要嘗試使用wait()
和notify()
與鎖對象再次進行同步。(實際上,它沒有按預期工作,幾個線程可以在同一個鎖對象上調用lock.isLocked()
並得到false直到任何一個線程調用lock.lock()
,但鎖定和解鎖之間的所有操作一次只能由單個線程執行)。
另外,通常的良好做法是在finally塊中調用lock.unlock()
。
我會使用synchronized
做一個簡單的方法。
class UserMaps {
private Map<Integer, User> users = new ConcurrentHashMap<>();
private Map<String, User> usersByName = new ConcurrentHashMap<>();
private Map<String, User> usersByEmail = new ConcurrentHashMap<>();
public synchronized int put(User user) {
users.put(user.getId(), user);
usersByName.put(user.getUsername(), user);
usersByEmail.put(user.getEmail(), user);
return user.getId();
}
}
只要您的所有getter也都synchronized
,這將確保所有地圖都一致更新。
但是,如果您想要更好的性能,並且希望避免所有方法都synchronized
,請使用ReadWriteLock
。
class UserMaps {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private Map<Integer, User> users = new ConcurrentHashMap<>();
private Map<String, User> usersByName = new ConcurrentHashMap<>();
private Map<String, User> usersByEmail = new ConcurrentHashMap<>();
public int saveUserToMap(User user) {
lock.writeLock().lock();
try {
users.put(user.getId(), user);
usersByName.put(user.getUsername(), user);
usersByEmail.put(user.getEmail(), user);
return user.getId();
} finally {
lock.writeLock().unlock();
}
}
public User getById(int id) {
lock.readLock().lock();
try {
return users.get(id);
} finally {
lock.readLock().unlock();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.