【发布时间】:2017-11-08 07:38:35
【问题描述】:
在下面的测试用例中,update() 方法在类外部调用,该类每小时仅由一个线程运行。但是有多个线程同时调用getKey1()和getKey2()。
所以对于这个用例:
最重要的是getKey1()和getKey2()几乎是同时调用的,一定要确定
- 如果 flag 为真,更新 key1 和 key2 并返回新密钥
- 如果没有,获取旧的key1和key2
我们不希望这种情况存在:更新key1并获取旧key2,但是即使我们已经更新了旧key1和key2,也可以获取少量请求。
public class Test {
private Lock lock = new ReentrantLock();
private AtomicBoolean flag1 = new AtomicBoolean(false);
private AtomicBoolean flag2 = new AtomicBoolean(false);
private volatile String key1;
private volatile String key2;
public Test(String key1, String key2) {
this.key1 = key1;
this.key2 = key2;
}
public void update() {
lock.lock();
try {
flag1.compareAndSet(false, true);
flag2.compareAndSet(false, true);
} finally {
lock.unlock();
}
}
public String getKey1() {
// TODO if the lock is holding... block over here
if (flag1.get()) {
// doing something for key 1
key1 = getFromFile();
flag1.set(false);
}
return key1;
}
public String getKey2() {
// TODO if the lock is holding... block over here
if (flag2.get()) {
// doing something for key 1
key2 = getFromFile();
flag2.set(false);
}
return key1;
}
}
我的想法是:
- update() 运行时,阻止
getKey1()和getKey2(),等待获取更新密钥 - update() 未运行时,
getKey1()和getKey2()应该都可以,直接返回。 - 当调用 getKey1() 或 getKey2() 时,我认为我们不需要阻塞 update() 方法。
有人对实现有任何想法吗?
【问题讨论】:
-
在 getKey1() 和 getKey2() 中都使用 lock.tryLock()
-
你确定
ReentrantLock是你需要的吗?你考虑过ReadWriteLock
标签: java multithreading concurrency atomic volatile