I would use a CountDownLatch
instead of reimplementing the logic.
I would also probably avoid starting a new Thread from the constructor, because it can lead to subtle concurrency bugs - instead you can simply make the genKey
method public and add the relevant javadoc (this method must be called first blabla):
public class KeyManager {
private volatile boolean genStarted = false;
private final CountDownLatch keyGenerated = new CountDownLatch(1);
private String key;
public void genKey() {
genStarted = true;
new Thread(new Runnable() {
public void run() {
key = operationThatTakesALongTime();
keyGenerated.countDown();
}
}).start();
}
public String getKey() throws InterruptedException {
if (!genStarted) throw new IllegalStateException("you must run genKey first");
keyGenerated.await();
return key;
}
}