【发布时间】:2017-06-18 17:15:30
【问题描述】:
我有一个由多个线程访问的类,我想确保它是线程安全的。另外,它需要尽可能快。这只是一个例子:
public class SharedClass {
private final Map<String, String> data = new HashMap<>();
private final Striped<ReadWriteLock> rwLockStripes = Striped.readWriteLock(100);
public void setSomethingFastVersion(String key, String value) {
ReadWriteLock rwLock = rwLockStripes.get(key);
try {
rwLock.lock();
} finally{
rwLock.unLock();
}
data.put(key, value);
}
public synchronized void setSomethingSlowVersion(String key, String value) {
data.put(key, value);
}
}
我在一个版本中使用来自 Google Guava 的 StripedLock,在另一个版本中使用普通的 synchronized。
Guava 版本应该更快吗?
如果是这样,什么是 synchronized 的好用例,而 StripedLocks 不适合?
顺便说一句,我知道我可以在这里使用简单的ConcurrentHashMap,但我正在添加示例代码以确保您理解我的问题。
【问题讨论】:
-
首先,您的
data.put(k,v)需要在您的try块内。通常,托管的特定锁比同步更快。基准测试将确定您的情况是否属实。您还在这里使用了读写锁。你需要那种行为吗?我在这里没有看到任何读取,您将如何实现它们? -
@WillD 那么你可以用什么来代替
ReadWriteLock呢? -
这里要考虑的其他一点是您是否需要锁定/同步。即使像这样同步,最后一个调用者也会设置值。如果您无法控制方法访问顺序,则无法确定结果。通常,我们锁定地图以确保基于
get(k)的某些功能在get(k)和put(k,v)之间没有任何变化。像putIfAbsent()onConcurrentMap这样的方法会在内部为您进行锁定,但put(k,v)不是并发的。
标签: java multithreading locking