CompletableFuture, supplyAsync() and thenApply() - multithreading

Need to confirm something. The following code:
CompletableFuture
.supplyAsync(() -> {return doSomethingAndReturnA();})
.thenApply(a -> convertToB(a));
would be the same as:
CompletableFuture
.supplyAsync(() -> {
A a = doSomethingAndReturnA();
convertToB(a);
});
Right?
Furthermore, another two questions following as for "is there any reason why we would use thenApply?"
1) having big code for conversion?
or
2) need to reuse the lambda block in other places?

It is not the same thing. In the second example where thenApply is not used it is certain that the call to convertToB is executed in the same thread as the method doSomethingAndReturnA.
But, in the first example when the thenApply method is used other things can happen.
First of all, if the CompletableFuture that executes the doSomethingAndReturnA has completed, the invocation of the thenApply will happen in the caller thread. If the CompletableFutures hasn't been completed the Function passed to thenApply will be invoked in the same thread as doSomethingAndReturnA.
Confusing? Well this article might be helpful (thanks #SotiriosDelimanolis for the link).
I have provided a short example that illustrates how thenApply works.
public class CompletableTest {
public static void main(String... args) throws ExecutionException, InterruptedException {
final CompletableFuture<Integer> future = CompletableFuture
.supplyAsync(() -> doSomethingAndReturnA())
.thenApply(a -> convertToB(a));
future.get();
}
private static int convertToB(final String a) {
System.out.println("convertToB: " + Thread.currentThread().getName());
return Integer.parseInt(a);
}
private static String doSomethingAndReturnA() {
System.out.println("doSomethingAndReturnA: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "1";
}
}
And the output is:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: ForkJoinPool.commonPool-worker-1
So, when the first operation is slow (i.e. the CompletableFuture is not yet completed) both calls occur in the same thread. But if the we were to remove the Thread.sleep-call from the doSomethingAndReturnA the output (may) be like this:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: main
Note that convertToB call is in the main thread.

thenApply() is a callback function, which will be executed when supplyAsync() return a value.
In code snippet 2, the thread which invoked doSomethingAndReturnA() waits for the function to get executed and return the data.
But in some exceptional cases (like making Webservice call and waiting for response), the thread has to wait for long time to get the response, which badly consumes lot of system computation resources (just waiting for response).
To avoid that, CompletableFuture comes with callback feature, where once the doSomethingAndReturnA() is invoked, a separate thread will take care of executing doSomethingAndReturnA() and the main caller thread will continue to do other operations without waiting for the response to return.
Once the response of doSomethingAndReturnA is available, the call back method will be invoked (i.e., thenApply())

Related

check asynchronous threads state in java

I have method in class MyClassB which is triggered asynchronously from a method of MyClassA:
public void getProductCall()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
productRequest = service.createS4ProductRequest(getRepriceItems());
//Below is a rest call to another system
String response = pricing.getS4ProductResponse(quote.getAssetQuoteNrAndVrsn(), productRequest);
//I'm using the below 2 lines to check from ClassA's method to see if this process has ended
setProductResponse(response);
productPriceProcessEnded=true;
} catch (Exception e) {
productPriceErrorOccured=true;
e.printStackTrace();
}
}
}).start();
}
This is the piece of code in MyClassA i used to check if the above method is complete.
for(int i=0;i<1000000000;i++)
{
if(!networkAsynCalls.isListPriceErrorOccured())
{
if(networkAsynCalls.isListPriceprocessEnded())
{
return networkAsynCalls.getListReponse();
}
else
{
Thread.sleep(250);
continue;
}
}
else
return null;
}
instead of using this random for loop can i use some inbuilt method or service pool or something ?
Because,
1) This thread on method is in another class
2) In class MyClassB i have few more methods like this, so i need to check the status of all the methods in MyClassA
Thanks for any help.
If I undestand what you're trying to do is dispatch some code to be ran asynchronously, then be able to wait until it is completed (successfully or failed). If that's the case, you should take a look at Futures.
Here is an example based on the Javadoc:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
// do stuff
return "result";
}});
This code creates an object "future" that can be invoked to execute searcher.search(target). At this point, the code is not executed at all. You simply have an object representing a computation that may be executed asynchronously. To do so, you'd call:
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(future);
This snippet created an Executor (which is a fixed pool of 5 threads), then handed over the future to it for execution. The executor will run the computation from Future asynchronously.
Future offers some methods (see the Javadoc) to wait until completion, cancel, check completion status, etc. For example,
String result = future.get();
will block, waiting for the result indefinitely. A get(10, TimeUnit.SECONDS) will wait for 10 seconds and if the future has not completed, throw.

Retrofit, call.enqueue

Here is my code:
retrofit2.Call<User> call = MainActivity.apiInterface.performUserLogin (username,password);
Log.d(TAG,"retrofit");
call.enqueue (new Callback<User> () {
#Override
public void onResponse( retrofit2.Call<User> call, Response<User> response )
{
Log.d (TAG,"in");
if(response.body ().getResponse ().equals ("ok"))
{
Log.d (TAG,"ok");
MainActivity.prefConfig.writeLoginStatus (true);
loginFormActivityLisener.performLogin (response.body ().getName ());
}
else if(response.body ().getResponse ().equals ("failed"))
{
MainActivity.prefConfig.displayToast ("Login Failed... Please try again...");
Log.d(TAG,"failed");
}
}
#Override
public void onFailure( retrofit2.Call<User> call, Throwable t ) {
}
});
I have question, why call.enqueue is not working? It is like it wasnt there. Its do nothing.
enqueue() function of Retrofit works asynchronously. It is a background task and runs the request on a background thread. If you debug your code, you will most probably see debugger skips the enqueue call and continues to execute next line. When background thread finishes, after skipping a few more lines maybe, it gets back to call.enqueue().
If you want to use a foreground task, you can choose execute() function, or there are other implementations to wait main thread until callback responses, like using events (see EventBus library).

What is the purpose of await() in CountDownLatch?

I have the following program, where I am using java.util.concurrent.CountDownLatch and without using await() method it's working fine.
I am new to concurrency and want to know the purpose of await(). In CyclicBarrier I can understand why await() is needed, but why in CountDownLatch?
Class CountDownLatchSimple:
public static void main(String args[]) {
CountDownLatch latch = new CountDownLatch(3);
Thread one = new Thread(new Runner(latch),"one");
Thread two = new Thread(new Runner(latch), "two");
Thread three = new Thread(new Runner(latch), "three");
// Starting all the threads
one.start(); two.start(); three.start();
}
Class Runner implements Runnable:
CountDownLatch latch;
public Runner(CountDownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName()+" is Waiting.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
System.out.println(Thread.currentThread().getName()+" is Completed.");
}
OUTPUT
two is Waiting.
three is Waiting.
one is Waiting.
one is Completed.
two is Completed.
three is Completed.
CountDownLatch is the synchronization primitive which is used to wait for all threads completing some action.
Each of the thread is supposed to mark the work done by calling countDown() method. The one who waits for the action to be completed should call await() method. This will wait indefinitely until all threads mark the work as processed, by calling the countDown(). The main thread can then continue by processing the worker's results for example.
So in your example it would make sense to call await() at the end of main() method:
latch.await();
Note: there are many other use cases of course, they don't need to be threads but whatever that runs usually asynchronously, the same latch can be decremented several times by the same task etc. The above describes just one common use case for CountDownLatch.

Qt code sequence in multithread. Is this possible?

This is objectA which subclass QThread
void run()
{
while (continue)
emit query();
}
void work(int input, bool workdone)
{
// work hard here
if (workdone) { continue = false; }
}
This is some code in main object
{
ObjectA A* = new ObjectA(this);
connect(A, SIGNAL(query()), this, SLOT(handleQuery()));
objectA.start();
}
void handleQuery()
{
A.work(interger, allJobDONE);
}
OK, I don't know how to name the question. Basically, it is just "will this code work?" If yes, how would be the code sequence?
Let me explain my question. ObjectA is a thread. It is going to query information from time to time by emitting a query signal. When the query signal is grubbed by the main code, the main code decide whether there is job so as to send the job to ObjectA by calling work() function.
If this code works, both the run() and the work() function in the same object work at the same time. Is this possible?
There are few problems:
the function ObjectA::run() blocks the event loop of the thread;
A.work() is called from the wrong thread;
it is needed to think about proper deletion of A.
Instead of blocking while loop in run() it is better to use timer. However, in that case the thread event loop should be executed (that it done in the default implementation of QThread::run(). So some other member slot should be used for that task to start, for example:
void ObjectA::doLoop()
{
emit query();
QTimer::singleShot(0, this, SLOT(doLoop()));
}
That function should be called when the thread is started, for example it can be done by connection in ObjectA constructor:
connect(this, SIGNAL(started()), this, SLOT(doLoop()));
Even better to keep private pointer QTimer* to be able to stop that timer from work() or to have some other control. Note that in that case QTimer object should be in the same thread as ObjectA.
Normally the ObjectA::work() function should be triggerd by some signal from handleQuery(). The event loop of ObjectA will catch that signal and the work() will be started in ObjectA thread.

Multithreading - how to invoke Action

I have some menu popup with action buttons. This is popup so it is made in new thread. I add event to created buttons something like this:
private StdProcedure m_ToInvoke;
public void AddButton()
{
Button myChildTempButton = new Button();
myChildTempButton.ItemClick += new ItemClickEventHandler((x, y) =>
{
HidePopup(); m_ToInvoke = myOpp.Procedure;
});
}
StdProcedure is delegate
public delegate void StdProcedure();
And after close event:
protected override void OnPopupClosed()
{
base.OnPopupClosed();
if (m_ToInvoke != null) m_ToInvoke.Invoke();
}
That doesn't work correctly. Sometime invoked operations stopped my another thread and I don't understand how it's works.
My question is what is the different between:
m_ToInvoke()
m_ToInvoke.Invoke()
m_ToInvoke.BeginInvoke()
m_ToInvoke.DynamicInvoke()
and what should I use here?
For me first and second is the same in effect.
m_ToInvoke() is just C# syntactic sugar for m_ToInvoke.Invoke()
m_ToInvoke.Invoke() executes the delegate synchronously, in the same thread
m_ToInvoke.BeginInvoke() schedules the delegate for invocation in a thread-pool thread; the returned IAsyncResult can be used to wait for it to complete, and you can also pass in a callback
m_ToInvoke.DynamicInvoke() is the only one of these methods to be declared by Delegate - it's similar to calling it by reflection, in that there's no compile-time safety for the number/type of the arguments etc.
Note that calling Invoke/BeginInvoke on a delegate is very different to calling Dispatcher.Invoke/BeginInvoke or Control.Invoke/BeginInvoke, which are to do with invoking a delegate within the UI thread for a WPF/WinForms app - although again, the Invoke version is synchronous and BeginInvoke is asynchronous.

Resources