I am newbie in Vert.x.
For example, JDBCClient has non-blocking method
JDBCClient.getConnection(Handler<AsyncResult<SQLConnection>> handler)
When I call it, it is really asynchronous.
jdbcClient.getConnection(result -> { /* this code will execute asynchonous */})
But how can I implement my own component with non-blocking methods?
When I write for example this, it doesnt looks asynchronous. It just will execute method body and then will call passed lambda.
class MyComponent {
public void getSomething(Handler<AsyncResult<String>> handler) {
String result = someHeavyMethodInThisThread();
handler.handle(Future.succeededFuture(result));
}
}
/* later */
/* this code will be blocking, right? */
myComponent.getSomething(res -> { /* ... */ })
Maybe there is way to tell Vert.x that my method should be asynchronous? Some annotation or something else?
There is nothing wrong with your code, your code style, normally will be async because the moment you perform a IO operation or call a vert.x API a async operation will detach you from the current thread (event loop).
In your case you're doing CPU bound code so it does not behave as async and as you stated will just call the lambda. If you want nevertheless make it async you can always wrap your code with runOnContext and that will enqueue it to be run on the next iteration of the event loop, e.g.:
class MyComponent {
public void getSomething(Handler<AsyncResult<String>> handler) {
vertx.runOnContext(v -> {
String result = someHeavyMethodInThisThread();
handler.handle(Future.succeededFuture(result));
});
}
}
Related
I want to release current thread when invoking a blocking call and continue when the call returns in asynchronous coding in java. The example is as follows:
public class Thread1 implements Runnable {
public void run() {
someBlockingCall(); // when do this calling, I want the current thread can be relased to do some other stuff, like execute some other Runnable object
getResult(); // when return from the blocking call, something can inform the thread to continue executing, and we can get the result
}
}
How can I realize this? Please help me.
You need to explicitly call someBlockingCall() asynchronously, then block to wait for the result when it's due
public void run() {
CompletableFuture<ResultType> result =
CompletableFuture.supplyAsync(() -> someBlockingCall());
//do some other work here while someBlockingCall() is running async
//this other work will be done by the first (main?) thread
ResultType finalResult = result.join(); //get (or wait for) async result
//Now use the result in the next call
getResult();
}
If someBlockingCall() has a void return type, you can use CompletableFuture.runAsync(() -> someBlockingCall());, with the future being of type CompletableFuture<Void>
In conclusion, currently there is no way to realize my thought as I wrote in this question, because you can not just make two parallele statements execute in two different threads.
I would like to use a Java Library inside of my Kotlin Android App, but I am relatively new to Kotlin and need some advice. The Library basically looks like this:
public interface Listener{
void onResult(Result res)
}
public class Client{
public Client(){}
public void setListener(Listener l){}
public void start(){} // Starts Thread(s) (so it's non-blocking), does some server calls, computes result, calls listener.onResult(res) after computation is finished.
public void cancel(){}
}
Yes, I know, I could just call the functions directly and use it like in java, but is that the Kotlin way?
I read, doing a similar task (using an asynchronous function, which takes a callback parameter) would be done by wrapping it in a coroutine/suspend function structure.
But I don't know howto adapt this for my Problem(?) or is it the wrong approach?
If you want to make this into a nice easy Kotlin suspending function, it would be like this:
suspend fun doTheThing() : Result {
val c = Client()
try {
//suspend until the listener fires or we're cancelled
return suspendCancellableCoroutine {
cont ->
c.setListener {
result -> cont.resume(result)
}
c.start()
}
} catch (e: Exception) {
// If someone cancels the parent job, our job will complete exceptionally
// before the client is done. Cancel the client since we don't need it
// anymore
c.cancel()
throw e
}
}
I don't see a way in your interface for the client to indicate failure. If that's part of Result then you probably want to turn that into an exception in the listener
I am new to multithreading concept in java(springboot) and have a scenario to solve.There is a function in which 2 asynchronus functions are called.I want to make their execution happen synchronously.eg:
public void func(){
call1();
call2();
}
#Async
public void call1(){}
#Async
public void call2(){}
Can anyone please suggest a method to achieve this functionality.
Thanks
Not exactly sure whats the motivation over here, but from what I could understand from the question, the objective seems like that you dont want to block the main thread (thread executing func()), and at the same time achieve serial execution of call1() and call2(). If thats what you want, you could perhaps make call1() and call2() synchronous (i.e. remove the #Async annotation), and add a third asynchronous method (callWrapper() perhaps), and invoke call1() and call2() serially in that method.
You can wait on #Async methods if you change them to return a Future. For example like this:
#Component
class AsyncStuff {
#Async
public ListenableFuture<?> call1() {
/** do things */
return AsyncResult.forValue(null);
}
#Async
public ListenableFuture<?> call2() {
/** do other things */
return AsyncResult.forValue(null);
}
}
#Component
class User {
#Autowired
AsyncStuff asyncStuff; // #Async methods work only when they are in a different class
public void use() throws InterruptedException, ExecutionException {
asyncStuff
.call1() // starts this execution in another thread
.get(); // lets this thread wait for the other thread
asyncStuff
.call2() // now start the seconds thing
.get(); // and wait again
}
}
But it's guaranteed to be slower than simply doing all this without async because all this adds is overhead to move execution between threads. The calling thread could instead of waiting for other threads to do things simply execute the code itself in that time.
I tried hard but didn't find any article or blog which clearly compares ListenableFuture and CompletableFuture, and provides a good analysis.
So if anyone can explain or point me to such a blog or article, it will be really good for me.
Both ListenableFuture and CompletableFuture have an advantage over its parent class Future by allowing the caller to "register" in one way or another a callback to be called when the async action has been completed.
With Future you can do this:
ExecutorService executor = ...;
Future f = executor.submit(...);
f.get();
f.get() gets blocked until the async action is completed.
With ListenableFuture you can register a callback like this:
ListenableFuture listenable = service.submit(...);
Futures.addCallback(listenable, new FutureCallback<Object>() {
#Override
public void onSuccess(Object o) {
//handle on success
}
#Override
public void onFailure(Throwable throwable) {
//handle on failure
}
})
With CompletableFuture you can also register a callback for when the
task is complete, but it is different from ListenableFuture in that it can be completed from any thread that wants it to complete.
CompletableFuture completableFuture = new CompletableFuture();
completableFuture.whenComplete(new BiConsumer() {
#Override
public void accept(Object o, Object o2) {
//handle complete
}
}); // complete the task
completableFuture.complete(new Object())
When a thread calls complete on the task, the value received from a call to get() is set with the parameter value if the task is not already completed.
Read about CompletableFuture
Guava AbstractFuture has its limitations:
Listener is lists, but usually only 1 used - overkill. If multiple listeners are needed, handle it inside the next stage, or think about messaging.
setException set return value as Exception, so user has to use instanceof to differentiate Exception or not at get() like guava AbstractFuture did.
In Future pipeline, too many layers addListener() make code hard to read.
I prefer CompletableFuture.supply().thenApply().thenAccept().handle()
Suppose I'm working with the following callback API:
/**
* Registers a new action which will be run at some later time on
* some other thread, clearing any previously set callback action.
*
* #param callback an action to be run later.
* #returns the previously registered action.
*/
public Runnable register(Runnable callback);
I'd like to register my own action, but I want to preserve any set behavior. In other words I'd like my action to look something like:
new Runnable() {
public void run() {
// do my work
originalCallback.run();
}
}
What's the cleanest way to provide originalCallback to my Runnable?
The naive solutions that come to mind risk introducing a window of time where originalCallback isn't available when the callback is called, or that involve some intricate locking.
After some more digging I found Guava's SettableFuture and Java 8's CompletableFuture. I'll leave my BlockingSupplier up for posterity, but either of these Future implementations would be more standard, and work just the same.
You basically need a holder class with a blocking get() method. Something like this:
public class BlockingSupplier<E> implements Supplier<E> {
private final CountDownLatch latch = new CountDownLatch(1);
private volatile E value;
public synchronized void set(E value) {
checkState(latch.getCount() > 0, "Cannot call set more than once.");
this.value = value;
latch.countDown();
}
#Override
public E get() {
latch.await(); // will block until set() is called
return value;
}
}
Then you can use it like so:
BlockingSupplier<Runnable> supplier = new BlockingSupplier<>();
// Pass the BlockingSupplier to our callback
DecoratorCallback myAction = new DecoratorCallback(supplier);
// Register the callback, and set the BlockingSupplier to the old callback
supplier.set(register(myAction));
Where DecoratorCallback's run() looks like this:
public void run() {
// do my work
// This will block until supplier.set() returns
originalCallbackSupplier.get().run();
}
As durron597 mentions there are better ways to design a callback API, but given the API in the question, this seems reasonable.
This is a terrible way to have an API. The Single Responsibility Principle applies here. The way you are doing it now, your runnable is responsible for:
Whatever it's other job is
Calling the other callback.
You are breaking SRP inherently in your API design! Every class that uses this API is already broken from the getgo.
Fortunately, you can easily solve this problem with Guava's ListenableFuture, which works like this:
Submit the task
Get ListenableFuture object back
Attach callbacks with Futures.addCallback
Doing it this way ensures that your system puts the code for managing multithreading and happensBefore relationships in one place, and the code that actually does the work in another.