Skip to content

Instantly share code, notes, and snippets.

@prasannaboppe
Created February 21, 2020 06:00
Show Gist options
  • Save prasannaboppe/0af563860b90353032e9f744c900b3f7 to your computer and use it in GitHub Desktop.
Save prasannaboppe/0af563860b90353032e9f744c900b3f7 to your computer and use it in GitHub Desktop.
Wrapping an asynchronous computation into a synchronous (blocking) computation.
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ComputationFuture<T> implements Future<T> {
private volatile T result = null;
private volatile boolean cancelled = false;
private final CountDownLatch countDownLatch;
public ComputationFuture() {
countDownLatch = new CountDownLatch(1);
}
@Override
public boolean cancel(final boolean mayInterruptIfRunning) {
if (isDone()) {
return false;
} else {
countDownLatch.countDown();
cancelled = true;
return !isDone();
}
}
@Override
public T get() throws InterruptedException {
countDownLatch.await();
return result;
}
@Override
public T get(final long timeout, @NotNull final TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
countDownLatch.await(timeout, unit);
return result;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public boolean isDone() {
return countDownLatch.getCount() == 0;
}
public void onResult(final T result) {
this.result = result;
countDownLatch.countDown();
}
}
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class MainClass {
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
RestApiManager manager;
ComputationFuture<SomeData> future = new ComputationFuture<>();
manager.getSomeData(new OnSomeDataListener() {
@Override
public void onSuccess(SomeData response) {
future.onResult(response);
}
@Override
public void onFailed() {
future.onResult(null);
}
});
SomeData someData = future.get(3, TimeUnit.SECONDS);
}
}
@prasannaboppe
Copy link
Author

Here future.get() will block until the result comes, you can mention the timeout like above

@AleMuzzi
Copy link

AleMuzzi commented Dec 16, 2021

Hi, really useful implementation, however, I don't see the point in implementing the Future<> interface.
I have tested your class removing the implementation and the @OverRide attributes and it works just as well as before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment