How do I "cancel" a CountDownLatch? - java

I have multiple consumer threads waiting on a CountDownLatch of size 1 using await(). I have a single producer thread that calls countDown() when it successfully finishes.
This works great when there are no errors.
However, if the producer detects an error, I would like for it to be able to signal the error to the consumer threads. Ideally I could have the producer call something like abortCountDown() and have all of the consumers receive an InterruptedException or some other exception. I don't want to call countDown(), because this requires all of my consumer threads to then do an additional manual check for success after their call to await(). I'd rather they just receive an exception, which they already know how to handle.
I know that an abort facility is not available in CountDownLatch. Is there another synchronization primitive that I can easily adapt to effectively create a CountDownLatch that supports aborting the countdown?

JB Nizet had a great answer. I took his and polished it a little bit. The result is a subclass of CountDownLatch called AbortableCountDownLatch, which adds an "abort()" method to the class that will cause all threads waiting on the latch to receive an AbortException (a subclass of InterruptedException).
Also, unlike JB's class, the AbortableCountDownLatch will abort all blocking threads immediately on an abort, rather than waiting for the countdown to reach zero (for situations where you use a count>1).
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class AbortableCountDownLatch extends CountDownLatch {
protected boolean aborted = false;
public AbortableCountDownLatch(int count) {
super(count);
}
/**
* Unblocks all threads waiting on this latch and cause them to receive an
* AbortedException. If the latch has already counted all the way down,
* this method does nothing.
*/
public void abort() {
if( getCount()==0 )
return;
this.aborted = true;
while(getCount()>0)
countDown();
}
#Override
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
final boolean rtrn = super.await(timeout,unit);
if (aborted)
throw new AbortedException();
return rtrn;
}
#Override
public void await() throws InterruptedException {
super.await();
if (aborted)
throw new AbortedException();
}
public static class AbortedException extends InterruptedException {
public AbortedException() {
}
public AbortedException(String detailMessage) {
super(detailMessage);
}
}
}

Encapsulate this behavior inside a specific, higher-level class, using the CountDownLatch internally:
public class MyLatch {
private CountDownLatch latch;
private boolean aborted;
...
// called by consumers
public void await() throws AbortedException {
latch.await();
if (aborted) {
throw new AbortedException();
}
}
// called by producer
public void abort() {
this.aborted = true;
latch.countDown();
}
// called by producer
public void succeed() {
latch.countDown();
}
}

You can create a wrapper around CountDownLatch that provides the ability to cancel the waiters. It will need to track the waiting threads and release them when they timeout as well as remember that the latch was cancelled so future calls to await will interrupt immediately.
public class CancellableCountDownLatch
{
final CountDownLatch latch;
final List<Thread> waiters;
boolean cancelled = false;
public CancellableCountDownLatch(int count) {
latch = new CountDownLatch(count);
waiters = new ArrayList<Thread>();
}
public void await() throws InterruptedException {
try {
addWaiter();
latch.await();
}
finally {
removeWaiter();
}
}
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
try {
addWaiter();
return latch.await(timeout, unit);
}
finally {
removeWaiter();
}
}
private synchronized void addWaiter() throws InterruptedException {
if (cancelled) {
Thread.currentThread().interrupt();
throw new InterruptedException("Latch has already been cancelled");
}
waiters.add(Thread.currentThread());
}
private synchronized void removeWaiter() {
waiters.remove(Thread.currentThread());
}
public void countDown() {
latch.countDown();
}
public synchronized void cancel() {
if (!cancelled) {
cancelled = true;
for (Thread waiter : waiters) {
waiter.interrupt();
}
waiters.clear();
}
}
public long getCount() {
return latch.getCount();
}
#Override
public String toString() {
return latch.toString();
}
}

You could roll your own CountDownLatch out using a ReentrantLock that allows access to its protected getWaitingThreads method.
Example:
public class FailableCountDownLatch {
private static class ConditionReentrantLock extends ReentrantLock {
private static final long serialVersionUID = 2974195457854549498L;
#Override
public Collection<Thread> getWaitingThreads(Condition c) {
return super.getWaitingThreads(c);
}
}
private final ConditionReentrantLock lock = new ConditionReentrantLock();
private final Condition countIsZero = lock.newCondition();
private long count;
public FailableCountDownLatch(long count) {
this.count = count;
}
public void await() throws InterruptedException {
lock.lock();
try {
if (getCount() > 0) {
countIsZero.await();
}
} finally {
lock.unlock();
}
}
public boolean await(long time, TimeUnit unit) throws InterruptedException {
lock.lock();
try {
if (getCount() > 0) {
return countIsZero.await(time, unit);
}
} finally {
lock.unlock();
}
return true;
}
public long getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
public void countDown() {
lock.lock();
try {
if (count > 0) {
count--;
if (count == 0) {
countIsZero.signalAll();
}
}
} finally {
lock.unlock();
}
}
public void abortCountDown() {
lock.lock();
try {
for (Thread t : lock.getWaitingThreads(countIsZero)) {
t.interrupt();
}
} finally {
lock.unlock();
}
}
}
You may want to change this class to throw an InterruptedException on new calls to await after it has been cancelled. You could even have this class extend CountDownLatch if you needed that functionality.

Since Java 8 you can use CompletableFuture for this. One or more threads can call the blocking get() method:
CompletableFuture<Void> cf = new CompletableFuture<>();
try {
cf.get();
} catch (ExecutionException e) {
//act on error
}
another thread can either complete it successfully with cf.complete(null) or exceptionally with cf.completeExceptionally(new MyException())

There is a simple option here that wraps the CountDownLatch. It's similar to the second answer but does not have to call countdown repeatedly, which could be very expensive if the latch is for a large number. It uses an AtomicInteger for the real count, with a CountDownLatch of 1.
https://github.com/scottf/CancellableCountDownLatch/blob/main/CancellableCountDownLatch.java
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class CancellableCountDownLatch {
private final AtomicInteger count;
private final CountDownLatch cdl;
public CancellableCountDownLatch(int count) {
this.count = new AtomicInteger(count);
cdl = new CountDownLatch(1);
}
public void cancel() {
count.set(0);
cdl.countDown();
}
public void await() throws InterruptedException {
cdl.await();
}
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
return cdl.await(timeout, unit);
}
public void countDown() {
if (count.decrementAndGet() <= 0) {
cdl.countDown();
}
}
public long getCount() {
return Math.max(count.get(), 0);
}
#Override
public String toString() {
return super.toString() + "[Count = " + getCount() + "]";
}
}

Related

Why am I getting IllegalMonitorStateException with this code?

I have 2 threads, one calls get() method, another put() method.
I need to synchronize this methods in order to see result of get only after put. I do know how to do this other way, but I want to understand why am i getting .IllegalMonitorStateException with this code.
public class TransferObject {
private int value;
protected volatile boolean isValuePresent = false; //use this variable
public synchronized int get() {
synchronized (TransferObject.class) {
System.out.println("Got: " + value);
notify();
}
return value;
}
public void put(int value) {
synchronized (TransferObject.class) {
this.value = value;
System.out.println("Put: " + value);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Here is example of 2 threads.
public class ConsumerTask implements Runnable {
private TransferObject transferObject;
protected volatile boolean stopped;
public ConsumerTask(TransferObject transferObject) {
this.transferObject = transferObject;
new Thread(this, "ConsumerTask").start();
}
public void run() {
while (!stopped) {
transferObject.get();
}
}
public void stop() {
stopped = true;
}
}
public class ProducerTask implements Runnable {
private TransferObject transferObject;
protected volatile boolean stopped;
static volatile AtomicInteger i = new AtomicInteger(0);
public ProducerTask(TransferObject transferObject) {
this.transferObject = transferObject;
new Thread(this, "ProducerTask").start();
}
public void run() {
while (!stopped) {
transferObject.put(i.incrementAndGet());
}
}
public void stop() {
stopped = true;
}
}
You have two threads and one object for locking TransferObject.class.
When your thread ConsumerTask gets the lock, object TransferObject.class don't have sleeping threads, and when you call notify() for this monitor you get IllegalMonitorStateException
From the description for method notify:
Wakes up a single thread that is waiting on this object's monitor.
You don't have waiting treads for monitor TransferObject.class

How to put a infinite task(Runnable) give up for a while

As title, I want to make a Runnable rest for a while, then another task in ExecutorService has the chance to do its task.
Here the assumption:
public class Sample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executorService.execute(new Task());
}
}}
public class Task implements Runnable{
#Override
public void run() {
while(true) {
doTask();
// how to make this task give up for a while
// then other tasks in ExecutetorService have
// change to run like Thread.yield()?
// Thread.yield();
}
}
public void doTask() {
// assume it take some seconds to finish
}}
Thanks in advance.
ThreadPool will have maximum 5 Threads as per your construction and when you do Thread.sleep() or Thread.yield (to reduce it's priority but not anything guaranteed), it's making ThreadPool's thread to go sleep not your tasks so pending tasks from Queue won't get chance.
As an alternative option, you can make a queue which will hold half executed Tasks, you put tasks in this queue so you can execute after some time.
As I mentioned in my comment your tasks (Runnable/Callable) need to implement themselves some logic that can check to pause or resume. There are various ways to do that.
Also there is an example PausableThreadPoolExecutorin doc itself. The following code is taken from doc only:
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();
public PausableThreadPoolExecutor(...) { super(...); }
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch(InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}
The above code makes use of ReentrantLock to pause and resume.

ForkJoinPool resets thread interrupted state

I just noticed the following phenomena when cancelling a Future returned by ForkJoinPool. Given the following example code:
ForkJoinPool pool = new ForkJoinPool();
Future<?> fut = pool.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
while (true) {
if (Thread.currentThread().isInterrupted()) { // <-- never true
System.out.println("interrupted");
throw new InterruptedException();
}
}
}
});
Thread.sleep(1000);
System.out.println("cancel");
fut.cancel(true);
The program never prints interrupted. The docs of ForkJoinTask#cancel(boolean) say:
mayInterruptIfRunning - this value has no effect in the default implementation because interrupts are not used to control cancellation.
If ForkJoinTasks ignore interrupts, how else are you supposed to check for cancellation inside Callables submitted to a ForkJoinPool?
This happens because Future<?> is a ForkJoinTask.AdaptedCallable which extends ForkJoinTask, whose cancel method is:
public boolean cancel(boolean mayInterruptIfRunning) {
return setCompletion(CANCELLED) == CANCELLED;
}
private int setCompletion(int completion) {
for (int s;;) {
if ((s = status) < 0)
return s;
if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
if (s != 0)
synchronized (this) { notifyAll(); }
return completion;
}
}
}
It does not do any interruptions, it just sets status. I suppose this happens becouse ForkJoinPools's Futures might have a very complicated tree structure, and it is unclear in which order to cancel them.
Sharing some more light on top of #Mkhail answer:
Using ForkJoinPool execute() instead of submit() will force a failed Runnable to throw a worker exception, and this exception will be caught by the Thread UncaughtExceptionHandler.
Taking from Java 8 code:
submit is using AdaptedRunnableAction().
execute is using RunnableExecuteAction() (see the rethrow(ex)).
/**
* Adaptor for Runnables without results
*/
static final class AdaptedRunnableAction extends ForkJoinTask<Void>
implements RunnableFuture<Void> {
final Runnable runnable;
AdaptedRunnableAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
public final void run() { invoke(); }
private static final long serialVersionUID = 5232453952276885070L;
}
/**
* Adaptor for Runnables in which failure forces worker exception
*/
static final class RunnableExecuteAction extends ForkJoinTask<Void> {
final Runnable runnable;
RunnableExecuteAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
void internalPropagateException(Throwable ex) {
rethrow(ex); // rethrow outside exec() catches.
}
private static final long serialVersionUID = 5232453952276885070L;
}

Java Non Reentrant Lock Implementation

I have implemented a Non Reentrant Lock. I want to know if this has any mistakes, race conditions etc. I am aware of the fact that existing libraries have to be used (instead of writing our own), but this is just to see if I am understanding the java concurrency correctly. Any feedback is appreciated.
public class MyLock {
private boolean isLocked = false;
private long owner = -1;
private static String TAG = "MyLock: ";
public synchronized void Lock() throws InterruptedException, IllegalStateException {
if(!isLocked) {
isLocked = true;
owner = Thread.currentThread().getId();
} else {
if(owner == Thread.currentThread().getId()) {
throw new IllegalStateException("Lock already acquired. " +
"This lock is not reentrant");
} else {
while(isLocked == true) {
System.out.println(TAG+"Waiting for Lock, Tid = " +
Thread.currentThread().getId());
wait();
}
}
}
System.out.println(TAG+"Lock Acquired: Owner = " + owner);
}
public synchronized void Unlock() throws IllegalStateException {
if(!isLocked || owner != Thread.currentThread().getId()) {
throw new IllegalStateException("Only Owner can Unlock the lock");
} else {
System.out.println(TAG+"Unlocking: Owner = " + owner);
owner = -1;
isLocked = false;
notify();
}
}
}
Here is an implementation of a "standard" / "non-reentrant" lock in Java, as a wrapper around Java's built-in ReentrantLock that simply prevents the lock from ever being acquired more than once.
/**
* A "non-reentrant" lock, implemented as a wrapper around Java's ReentrantLock.
*
*/
class StandardLock implements java.util.concurrent.locks.Lock {
public static class LockAlreadyHeldException extends RuntimeException {}
private final java.util.concurrent.locks.ReentrantLock mainLock;
private void checkNotAlreadyHeld() {
if (mainLock.getHoldCount()!=0) {
throw new LockAlreadyHeldException();
}
}
public StandardLock() {
mainLock=new java.util.concurrent.locks.ReentrantLock();
}
public StandardLock(boolean fair) {
mainLock=new java.util.concurrent.locks.ReentrantLock(fair);
}
#Override
public void lock() {
checkNotAlreadyHeld();
mainLock.lock();
}
#Override
public void lockInterruptibly() throws InterruptedException {
checkNotAlreadyHeld();
mainLock.lockInterruptibly();
}
#Override
public boolean tryLock() {
checkNotAlreadyHeld();
return mainLock.tryLock();
}
#Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
checkNotAlreadyHeld();
return mainLock.tryLock(time, unit);
}
#Override
public void unlock() {
mainLock.unlock();
}
#Override
public Condition newCondition() {
return mainLock.newCondition();
}
}
The advantages to this approach are that the class implements Java's Lock interface, and Condition Variables thus come with it in order to allow the creation of Monitors. Monitors are important in order to fully leverage locks for concurrent programming.

Wrapping an asynchronous computation into a synchronous (blocking) computation

similar questions:
Pattern for wrapping an Asynchronous JavaScript function to make it synchronous
Wrapping an asynchronous method synchronously in C#
I have an object with a method I would like to expose to library clients (especially scripting clients) as something like:
interface MyNiceInterface
{
public Baz doSomethingAndBlock(Foo fooArg, Bar barArg);
public Future<Baz> doSomething(Foo fooArg, Bar barArg);
// doSomethingAndBlock is the straightforward way;
// doSomething has more control but deals with
// a Future and that might be too much hassle for
// scripting clients
}
but the primitive "stuff" I have available is a set of event-driven classes:
interface BazComputationSink
{
public void onBazResult(Baz result);
}
class ImplementingThing
{
public void doSomethingAsync(Foo fooArg, Bar barArg, BazComputationSink sink);
}
where ImplementingThing takes inputs, does some arcane stuff like enqueueing things on a task queue, and then later when a result occurs, sink.onBazResult() gets called on a thread that may or may not be the same thread as ImplementingThing.doSomethingAsync() was called.
Is there a way I can use the event-driven functions I have, along with concurrency primitives, to implement MyNiceInterface so scripting clients can happily wait on a blocking thread?
edit: can I use FutureTask for this?
Using your own Future implemenation:
public class BazComputationFuture implements Future<Baz>, BazComputationSink {
private volatile Baz result = null;
private volatile boolean cancelled = false;
private final CountDownLatch countDownLatch;
public BazComputationFuture() {
countDownLatch = new CountDownLatch(1);
}
#Override
public boolean cancel(final boolean mayInterruptIfRunning) {
if (isDone()) {
return false;
} else {
countDownLatch.countDown();
cancelled = true;
return !isDone();
}
}
#Override
public Baz get() throws InterruptedException, ExecutionException {
countDownLatch.await();
return result;
}
#Override
public Baz get(final long timeout, 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 onBazResult(final Baz result) {
this.result = result;
countDownLatch.countDown();
}
}
public Future<Baz> doSomething(Foo fooArg, Bar barArg) {
BazComputationFuture future = new BazComputationFuture();
doSomethingAsync(fooArg, barArg, future);
return future;
}
public Baz doSomethingAndBlock(Foo fooArg, Bar barArg) {
return doSomething(fooArg, barArg).get();
}
The solution creates a CountDownLatch internally which is cleared once the callback is received. If the user calls get, the CountDownLatch is used to block the calling thread until the computation completes and call the onBazResult callback. The CountDownLatch will assure that if the callback occurs before get() is called the get() method will return immediately with a result.
Well, there is the simple solution of doing something like:
public Baz doSomethingAndBlock(Foo fooArg, Bar barArg) {
final AtomicReference<Baz> notifier = new AtomicReference();
doSomethingAsync(fooArg, barArg, new BazComputationSink() {
public void onBazResult(Baz result) {
synchronized (notifier) {
notifier.set(result);
notifier.notify();
}
}
});
synchronized (notifier) {
while (notifier.get() == null)
notifier.wait();
}
return notifier.get();
}
Of course, this assumes that your Baz result will never be null…
The google guava library has an easy to use SettableFuture that makes this problem very simple (around 10 lines of code).
public class ImplementingThing {
public Baz doSomethingAndBlock(Foo fooArg, Bar barArg) {
try {
return doSomething(fooArg, barArg).get();
} catch (Exception e) {
throw new RuntimeException("Oh dear");
}
};
public Future<Baz> doSomething(Foo fooArg, Bar barArg) {
final SettableFuture<Baz> future = new SettableFuture<Baz>();
doSomethingAsync(fooArg, barArg, new BazComputationSink() {
#Override
public void onBazResult(Baz result) {
future.set(result);
}
});
return future;
};
// Everything below here is just mock stuff to make the example work,
// so you can copy it into your IDE and see it run.
public static class Baz {}
public static class Foo {}
public static class Bar {}
public static interface BazComputationSink {
public void onBazResult(Baz result);
}
public void doSomethingAsync(Foo fooArg, Bar barArg, final BazComputationSink sink) {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Baz baz = new Baz();
sink.onBazResult(baz);
}
}).start();
};
public static void main(String[] args) {
System.err.println("Starting Main");
System.err.println((new ImplementingThing()).doSomethingAndBlock(null, null));
System.err.println("Ending Main");
}
This is dead simple with RxJava 2.x:
try {
Baz baz = Single.create((SingleEmitter<Baz> emitter) ->
doSomethingAsync(fooArg, barArg, result -> emitter.onSuccess(result)))
.toFuture().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Or without Lambda notation:
Baz baz = Single.create(new SingleOnSubscribe<Baz>() {
#Override
public void subscribe(SingleEmitter<Baz> emitter) {
doSomethingAsync(fooArg, barArg, new BazComputationSink() {
#Override
public void onBazResult(Baz result) {
emitter.onSuccess(result);
}
});
}
}).toFuture().get();
Even simpler:
Baz baz = Single.create((SingleEmitter<Baz> emitter) ->
doSomethingAsync(fooArg, barArg, result -> emitter.onSuccess(result)))
.blockingGet();
Kotlin Version:
val baz = Single.create<Baz> { emitter ->
doSomethingAsync(fooArg, barArg) { result -> emitter.onSuccess(result) }
}.blockingGet()
A very simple example, just to understand CountDownLatch without any
extra code.
A java.util.concurrent.CountDownLatch is a concurrency construct that allows one or more threads to wait for a given set of operations to complete.
A CountDownLatch is initialized with a given count. This count is decremented by calls to the countDown() method. Threads waiting for this count to reach zero can call one of the await() methods. Calling await() blocks the thread until the count reaches zero.
Below is a simple example. After the Decrementer has called countDown() 3 times on the CountDownLatch, the waiting Waiter is released from the await() call.
You can also mention some TimeOut to await.
CountDownLatch latch = new CountDownLatch(3);
Waiter waiter = new Waiter(latch);
Decrementer decrementer = new Decrementer(latch);
new Thread(waiter) .start();
new Thread(decrementer).start();
Thread.sleep(4000);
public class Waiter implements Runnable{
CountDownLatch latch = null;
public Waiter(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Waiter Released");
}
}
//--------------
public class Decrementer implements Runnable {
CountDownLatch latch = null;
public Decrementer(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Reference
If you don't want to use a CountDownLatch or your requirement is something same as Facebook like and unlike functionality. Means if one method is being called then don't call the other method.
In that case you can declare a
private volatile Boolean isInprocessOfLikeOrUnLike = false;
and then you can check in the beginning of your method call that if it is false then call method otherwise return.. depends upon your implementation.
Here's a more generic solution based on Paul Wagland's answer:
public abstract class AsyncRunnable<T> {
protected abstract void run(AtomicReference<T> notifier);
protected final void finish(AtomicReference<T> notifier, T result) {
synchronized (notifier) {
notifier.set(result);
notifier.notify();
}
}
public static <T> T wait(AsyncRunnable<T> runnable) {
final AtomicReference<T> notifier = new AtomicReference<>();
// run the asynchronous code
runnable.run(notifier);
// wait for the asynchronous code to finish
synchronized (notifier) {
while (notifier.get() == null) {
try {
notifier.wait();
} catch (InterruptedException ignore) {}
}
}
// return the result of the asynchronous code
return notifier.get();
}
}
Here's an example how to use it::
String result = AsyncRunnable.wait(new AsyncRunnable<String>() {
#Override
public void run(final AtomicReference<String> notifier) {
// here goes your async code, e.g.:
new Thread(new Runnable() {
#Override
public void run() {
finish(notifier, "This was a asynchronous call!");
}
}).start();
}
});
A more verbose version of the code can be found here: http://pastebin.com/hKHJUBqE
EDIT:
The example related to the question would be:
public Baz doSomethingAndBlock(final Foo fooArg, final Bar barArg) {
return AsyncRunnable.wait(new AsyncRunnable<Baz>() {
#Override
protected void run(final AtomicReference<Baz> notifier) {
doSomethingAsync(fooArg, barArg, new BazComputationSink() {
public void onBazResult(Baz result) {
synchronized (notifier) {
notifier.set(result);
notifier.notify();
}
}
});
}
});
}
The simplest way (which works for me) is to
Create a blocking queue
Call the asynchronous method - use a handler that offers the result to that blocking queue.
Poll the queue (that's where
you block) for the result.
public Baz doSomethingAndBlock(Foo fooArg, Bar barArg) throws InterruptedException {
final BlockingQueue<Baz> blocker = new LinkedBlockingQueue();
doSomethingAsync(fooArg, barArg, blocker::offer);
// Now block until response or timeout
return blocker.poll(30, TimeUnit.SECONDS);
}

Categories

Resources