In the test case below, the update()
method is called outside of the class which in running for every hour by one thread only. But there have multiple threads calling getKey1()
and getKey2()
at the same time.
So for this use case:
The most important is since getKey1()
and getKey2()
are calling almost at the same time, we must make sure
- if flag is true, update both key1 and key2 and return the new key
- if not, get the old key1 and key2
We donot want such case exist: update the key1 and get the old key2, but it's ok to get the old key1 and key2 for few request even we already update it.
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;
}
}
My idea is:
- when update() is running, block both
getKey1()
andgetKey2()
, waiting to get the update key - when update() is not running,
getKey1()
andgetKey2()
should both be ok and return directly. - when calling either getKey1() or getKey2(), I think we do not need to block the update() method.
Anyone have any ideas about the implementation?