问题
First of all, I've decided to make my class blocking (to make it easier for the consumer to use - but maybe more tedious for me to write). As opposed to having the consumer define asynchronous callbacks. Is this a good design pattern? This way, a user can get expected behaviour, but implement their own multi-threading if they're dissatisfied with how long the thread's blocked for.
I've got a constructor that sets a final field in a class, based on the result of an async callback:
class Example {
private final int x;
Example(){
asyncFunc(/* callback */ result -> x = result)
}
}
This doesn't work, so I've used atomic references, and implemented a blocking loop, until the result it returned, like so:
class Example {
private final int x;
Example(){
x = waitAsyncFunc();
}
private int waitAsyncFunc(){
AtomicBoolean finished = new AtomicBoolean(false);
AtomicReference<byte[]> result = new AtomicReference<>();
asyncFunc(result -> {
result .set(res);
finished.set(true);
});
while (!finished.get()) { /* No op */ }
return result.get();
}
}
Is this a good way to block / retrieve the result?
回答1:
The simplest solution would be
class Example {
private final int x;
Example() {
CompletableFuture<Integer> f = new CompletableFuture();
asyncFunc(f::complete);
x = f.join();
}
}
But consider the alternative of waiting for the asynchronous job’s completion before even constructing the Example
instance.
回答2:
Instead of blocking the thread with a loop you can use a CountDownLatch.
As taken from the docs (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html)
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
Your code would look something like
private int waitAsyncFunc() throws InterruptedException {
CountDownLatch latch = new new CountDownLatch(1);
AtomicReference<byte[]> result = new AtomicReference<>();
asyncFunc(result -> {
result.set(res);
latch.countDown();
});
latch.await(); //You can even specify a timeout
return result.get();
}
来源:https://stackoverflow.com/questions/60188496/wait-for-callback-from-other-thread