英文:
Synchronising method evaluation based on value
问题
假设我有一个计算某个数字阶乘的方法。现在这是一个需要消耗大量 CPU 资源的任务,所以如果我的一个线程已经在计算某个数字的阶乘,那么我不应该再为相同的值调用阶乘计算方法。如何使用锁来实现这一点呢?并且由于阶乘值是不会改变的(除非定义发生变化 :)),我会将计算出的值放入一个映射(Map)中。
在使用 Map.get() 时不应该加锁,只有在进行计算并将结果放入映射时才需要加锁。
(阶乘只是一个例子,也可以是等待 I/O 响应的 HTTP 调用。)
英文:
Let's say I have a method which calculates factorial for a number. Now this is a cpu intensive task, so if 1 of my thread is already calculating factorial for a number i should not call the factorial method for same value again. How can this be achieved using locking? And since factorial values don't change (unless the definition does ), I would put the calculated values in a map.
Map.get() should not be locking but only when we have to do the calculation and put in map we should use locking.
(The Factorial is just and example it could be a http call which is waiting for io response.)
答案1
得分: 0
我最终使用了Guava的loadingCache来实现这个。
代码如下所示:
LoadingCache<Integer, Employee> empCache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<Integer, Employee>() {
@Override
public Employee load(Integer id) throws Exception {
// 在这里进行耗时操作
return getEmployeeById(id);
}
}
);
如果多个线程对同一个键进行get操作,getEmployeeById
方法只会被调用一次。
英文:
I ended up using Guava loadingCache for this.
this is how the code looks like
LoadingCache<Integer, Employee> empCache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<Integer, Employee>() {
@Override
public Employee load(Integer id) throws Exception {
//heavy operation here
return getEmployeeById(id);
}
}
);
If multiple thread do a get for same key, getEmployeeById will be called only once.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论