我正在设计一个缓存,我可以在其中保存安全价格,这些价格计算起来很耗时。计算完成后,我将它们存储在地图中:安全性作为关键,价格作为价值。简单的解决方案是在ConcurrentHashMap这里使用,但我正在尝试使用多线程程序来理解不同的锁定策略。
在这里,我正在尝试不同的方法来获取锁定,以防我需要更新进程缓存中的证券价格(它可以被视为任何实体类)。
第一种方式:在这里,我试图在我的缓存类中提供锁定,以便不需要客户端锁定。
第一种方式的问题:即使我需要更新一种证券的价格,我MyCache也会锁定所有证券,因为是单例,并且所有情况(putPrice 和 getPrice 方法调用)都使用相同的锁实例,因此所有其他正在尝试的线程更新其他证券也在等待锁定,尽管这可以并行完成。
第一种方式的代码:
class Security {
int secId;
}
// Singleton class MyCache
public class MyCache {
private static final HashMap<Security, BigDecimal> cache = new HashMap();
private final static ReadWriteLock lock = new ReentrantReadWriteLock();
public BigDecimal getPrice(Security security) {
lock.readLock().lock();
try {
BigDecimal price = cache.get(security);
if (price == null) {
price = new BigDecimal(-9999.9999);
}
return price;
} finally {
lock.readLock().unlock();
}
}
public void putPrice(Security security, BigDecimal price) {
lock.writeLock().lock();
try{
cache.put(security, price);
}finally {
lock.writeLock().unlock();
}
}
}
第二种方式:在这里,我试图获取对安全性的锁定,为此我在MyCache构造函数中使用了 Security(Instance Controlled class) 对象。MyCache不像第一种情况那样是单身。客户端代码需要实例化 MyCache 的新对象,传递 Security 对象。
第二种方式的问题:这里可能我增加了复杂性,如果应该通过 Security 获取锁为什么我们不在 Security 类中实现与锁定相关的代码,我们可以在那里提供 getPrice 和 updatePrice 方法并使用关键部分来阻止多个线程进入相同相同安全的时间(实例控制类,一个安全只有一个对象)。
第二种方式的代码:
class Security {
private int secId;
private final static HashMap<Integer, Security> map = new HashMap<>();
private Security(Integer secId) {
this.secId = secId;
}
public static synchronized Security getSecurity(Integer secId) {
Security security = map.get(secId);
if (security == null) {
security = new Security(secId);
map.put(secId, security);
}
return security;
}
}
湖上湖
蛊毒传说
相关分类