Java async servlet: Wait for a specific event - java

EDIT:
Edited the question in response to #maress answer below.
I have a web service in java (async enabled), which when called performs a call to another service asynchronously. In my Controller I have this:
private boolean receivedEvent = false;
private final Object SYNC = new Object();
public Callable<String> doStuff()
{
callSomeAsyncFunction();
return new Callable<String> ()
{
#Override
public String call() throws Exception {
synchronized (SYNC)
{
while (receivedEvent == false)
{
SYNC.wait();
}
receivedEvent = false;
System.out.println("RETURN");
return "ok";
}
}
};
}
public void onMyEvent(MyEvent event)
{
synchronized (SYNC)
{
receivedEvent = true;
System.out.println("RECEIVED");
SYNC.notify();
}
}
EDIT: The notification never gets through. System.out.println("RETURN") is never called. The events are being received ('RECEIVED' is shown).
Now all I want to do is wait for the callSomeAsyncFunction() to finish executing. When done, it triggers an event on the handler public void onMyEvent(MyEvent event).
Any suggestions? I am not even sure if my approach makes sense at all.

Synchronize always on a final instance.
private MyEvent myEvent;
private final Object SYNC = new Object();
public Callable<String> doStuff()
{
callSomeAsyncFunction();
return new Callable<String> ()
{
#Override
public String call() throws Exception {
synchronized (SYNC)
{
while (myEvent == null)
{
SYNC.wait();
}
return "ok";
}
}
};
}
public void onMyEvent(MyEvent event)
{
synchronized (SYNC)
{
myEvent = event;
SYNC.notifyAll();
}
}

Related

Java: Synchronization based on object value

I want to synchronize one method or one block based on input parameters.
So I have one API which has two inputs (let's say id1 and id2) of long type (could be primitive or wrapper) in post payload, which can be JSON. This API will be called by multiple threads at the same time or at different times randomly.
Now if the first API call has id1=1 and id2=1, and at the same time another API call has id1=1 and id2=1, it should wait for the first API call to finish processing before executing the second call. If the second API call has a different combination of values like id1=1 and id2=2, it should go through parallel without any wait time.
I don't mind creating a service method also which the API resource method can call, rather than handling directly at API resource method.
I'm using Spring boot Rest Controlller APIs.
**Edit**
I've already tried using map as suggested but this partially works. It waits for all input values, not just the same input values. Below is my code:
public static void main(String[] args) throws Exception {
ApplicationContext context = SpringApplication.run(Application.class, args);
AccountResource ar = context.getBean(AccountResource.class);
UID uid1 = new UID();
uid1.setFieldId(1);
uid1.setLetterFieldId(1);
UID uid2 = new UID();
uid2.setFieldId(2);
uid2.setLetterFieldId(2);
UID uid3 = new UID();
uid3.setFieldId(1);
uid3.setLetterFieldId(1);
Runnable r1 = new Runnable() {
#Override
public void run() {
while (true) {
ar.test(uid1);
}
}
};
Runnable r2 = new Runnable() {
#Override
public void run() {
while (true) {
ar.test(uid2);
}
}
};
Runnable r3 = new Runnable() {
#Override
public void run() {
while (true) {
ar.test(uid3);
}
}
};
Thread t1 = new Thread(r1);
t1.start();
Thread t2 = new Thread(r2);
t2.start();
Thread t3 = new Thread(r3);
t3.start();
}
#Path("v1/account")
#Service
public class AccountResource {
public void test(UID uid) {
uidFieldValidator.setUid(uid);
Object lock;
synchronized (map) {
lock = map.get(uid);
if (lock == null) {
map.put(uid, (lock = new Object()));
}
synchronized (lock) {
//some operation
}
}
}
}
package com.urman.hibernate.test;
import java.util.Objects;
public class UID {
private long letterFieldId;
private long fieldId;
private String value;
public long getLetterFieldId() {
return letterFieldId;
}
public void setLetterFieldId(long letterFieldId) {
this.letterFieldId = letterFieldId;
}
public long getFieldId() {
return fieldId;
}
public void setFieldId(long fieldId) {
this.fieldId = fieldId;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Override
public int hashCode() {
return Objects.hash(fieldId, letterFieldId);
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
UID other = (UID) obj;
return fieldId == other.fieldId && letterFieldId == other.letterFieldId;
}
}
You need a collection of locks, which you can keep in a map and allocate as required. Here I assume that your id1 and id2 are Strings; adjust as appropriate.
Map<String,Object> lockMap = new HashMap<>();
:
void someMethod(String id1, String id2) {
Object lock;
synchronized (lockMap) {
lock = lockMap.get(id1+id2);
if (lock == null) lockMap.put(id1+id2, (lock = new Object()));
}
synchronized (lock) {
:
}
}
You need a little bit of 'global' synchronization for the map operations, or you could use one of the concurrent implementations. I used the base HashMap for simplicity of implementation.
After you've selected a lock, sync on it.

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;
}

FutureTask with Callable that references the FutureTask

I have a situation where I need to create a FutureTask with a Callable that checks if it's owner has been cancelled. The code I have looks like this:
public static FutureTask<Result> makeFuture(final Call call, final TaskCompletionCallback completion) {
return new FutureTask<Result>(new Callable<Result>() {
#Override
public Result call() throws Exception {
Result result = CYLib.doNetworkRequest(call, new CarryOnCallback() {
#Override
public boolean shouldCarryOn() {
return !FutureTask.isDone();
}
});
return result;
}
});
}
Basically the doNetworkRequest asks the CarryOnCallback if it should continue at certain times during the operation. I would like for this callback to see if the FutureTask that is calling the doNetworkRequest was cancelled, which involves querying the actual FutureTask object.
Now I know that you can't really access 'this' because it hasn't been constructed yet. But is there a way around this, or a better design for my situation?
Cheers
EDIT:
Ok so I'm going about it like this now. Made a custom Callable and FutureTask. The Callable holds a reference to the FutureTask and this can be set manually after creating a new Callable:
public static MyTask makeMyTask(final Call call, final TaskCompletionCallback completion) {
MyTask task = null;
MyTask.InnerCallable innerCallable = new MyTask.InnerCallable(call, completion);
task = new MyTask(innerCallable);
innerCallable.setParent(task);
return task;
}
And just for reference, the InnerCallable looks like this:
public static class MyTask extends FutureTask<Result> {
InnerCallable callable;
public MyTask(InnerCallable callable) {
super(callable);
this.callable = callable;
}
private static class InnerCallable implements Callable<Result> {
private final Call call;
private final TaskCompletionCallback completion;
private WeakReference<MyTask> parentTask;
InnerCallable(Call call, TaskCompletionCallback completion) {
this.call = call;
this.completion = completion;
}
#Override
public Result call() {
Result result = CYLib.doNetworkRequest(this.call, new CarryOnCallback() {
#Override
public boolean shouldCarryOn() {
MyTask task = parentTask.get();
return !(task == null || task.isCancelled());
}
});
return result;
}
private void setParent(MyTask parentTask) {
this.parentTask = new WeakReference<MyTask>(parentTask);
}
}
}
So, your CYLib.doNetworkRequest() is working in another thread?
private static Map<Call,FutureTask> map=new HashMap();
public static FutureTask<Result> makeFuture(final Call call, final TaskCompletionCallback completion) {
FutureTask<Result> futureResult = new FutureTask<Result>(new Callable<Result>() {
#Override
public Result call() throws Exception {
Result result = CYLib.doNetworkRequest(call, new CarryOnCallback() {
#Override
public boolean shouldCarryOn() {
return !map.get(call).isCancelled();
}
});
return result;
}
});
map.put(call,futureResult);
return futureResult;
}

postDelayed sometime doesn't run in Android

I am running multiple thread and Handler in my code.
And this is my Handler
PrizeRunnable mTempPotionRunnable = new PrizeRunnable(aaa);
handler.postDelayed(mTempPotionRunnable, 4000);
and
class PrizeRunnable implements Runnable {
String type;
PrizeRunnable(String type) {
this.type = type;
}
public void run() {
synchronized (this) {
if(!mIsHandlerStarted){
if(type.equals(aaa))
// Do something
else if(type.equals(bbb))
// Do something
mIsHandlerStarted = true;
handler.removeCallbacks(this);
}
}
}
}
But sometime it run simultaneously.
i don not know the reason.
UPDATED
I try to change it to:
handler.postDelayed(mTempPotionRunnable, 4000);
and
Runnable mTempPotionRunnable = new Runnable() {
#Override
public void run() {
synchronized (this) {
if(!mIsHandlerStarted){
// Do something
mIsHandlerStarted = true;
handler.removeCallbacks(mMetalRunnable);
}
}
}
};
May be it resolve my problems. I am testing this method.
But i can't pass parameter to my Runnable . How can i do it?
My guess is that it's because you're synchronizing on the current instance:
synchronized (this) {
...
}
so unless you pass the same instance to all the handlers each one will use a different lock object. Try a static lock instead:
class PrizeRunnable implements Runnable {
String type;
private static final Object lock = new Object();
PrizeRunnable(String type) {
this.type = type;
}
public void run() {
synchronized (lock) {
if(!mIsHandlerStarted){
if(type.equals(aaa))
// Do something
else if(type.equals(bbb))
// Do something
mIsHandlerStarted = true;
handler.removeCallbacks(this);
}
}
}
}
Make global variable and i can pass parameter to my Runnable

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