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.
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.
Inside springboot when the thread gets executed successfully then only the required method should gets executed. Otherwise in case if thread gets killed abnormally dont want to execute any method just leave like that only.
I have to handle the successful thread execution scenario only with this.
for eg.
#Component
#Scope("prototype")
public class TestWatcher extends Thread
{
#Override
public void run()
{
//do something
}
//like destroy or something
public void afterThreadSuccessOnly()
{
//executes only on successful execution of run method.
}
}
I have tried this with springboot #PreDestroy annotation but it does not work if the component is prototype.
is there any solution to achieve this scenario, please anyone help me with that.
Assuming you mean to define 'success' as: Did not throw an exception and ran its natural course or executed a return statement, then, what's wrong with the rather obvious:
#Override
public void run() {
doJob();
afterThreadSuccessOnly();
}
public void doJob() {
// do something
}
public void afterThreadSuccessOnly() {
}
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));
});
}
}
Today I had to write a method which get a String as a parameter, make a new thread and write it out to the consol after 5 seconds waiting, so something like this:
public void exampleMethod(final String str){
Runnable myRunnable = new Runnable(){
public void run(){
try {
Thread.sleep(5000);
System.out.println(str);
} catch (InterruptedException e) {
//handling of the exception
}
}
};
Thread thread = new Thread(myRunnable);
thread.start();
//some other things to do
}
My question is: How can I test and what should I test in here with JUnit?
Thank you!
There is nothing complex in this method. You are only using standard API-methods: Thread.sleep, System.out.println, ...
The parameter is just printed, you don't modify it nor use it for a calculation or another method.
There are no side-effects to your own written code, just to the STL.
And there is no result of the method, which you could test.
In my opinion it is not necessary and not simply possible to test it.
The only thing you could test (and even that wouldn't be trivial), is, if after an amount of time the String is printed.
[...] JUnit finishes execution while the thread is still alive. There could have been problems down the line, toward the end of that thread's execution, but your test would never reflect it.
The problem lies in JUnit's TestRunner. It isn't designed to look for Runnable instances and wait around to report on their activities. It fires them off and forgets about them. For this reason, multithreaded unit tests in JUnit have been nearly impossible to write and maintain.
Well, the source - this article - is from 2003 and there's no guarantee that this hasn't been fixed yet, but you may try it out yourself.
My suggestion would be:
Run your code and measure the time it takes. Then add some 1000 milliseconds and but a Thread.sleep(executionTime+1000); after you started you asynchronous task. Not that elegant, but should work in practice. If you want more elegance here (and waste less time), you may want to look for framework that provide a solution.
...Or if you start your Thread directly in the test, you may also use Thread.join to wait, but you will have cases, where you aren't able to do that.
EDIT:
Also check this article, which could provide a solution to pipe those errors to the main thread:
public class AsynchTester{
private Thread thread;
private volatile Error error;
private volatile RuntimeException runtimeExc;
public AsynchTester(final Runnable runnable) {
thread = new Thread(new Runnable() {
#Override
public void run() {
try {
runnable.run();
} catch (Error e) {
error = e;
} catch (RuntimeException e) {
runtimeExc = e;
}
}
});
}
public void start() {
thread.start();
}
public void test() throws InterruptedException {
thread.join();
if (error != null)
throw error;
if (runtimeExc != null)
throw runtimeExc;
}
}
Use it like that:
#Test
public void test() throws InterruptedException {
AsynchTester tester = new AsynchTester(new Runnable() {
#Override
public void run() {
//async code
}
});
tester.start();
tester.test();
}
The issue here is that you are trying to test an interaction instead of a simple returned result or a state change. However, that does not mean it can't be done.
The standard out PrintStream can be replaced with System.setOut(). You can inject your own mock implementation that would allow you verify that the String was written to the stream. You just have to be careful, since this changes the global state, it might effect other code or tests that rely on standard output. At a minimum, you will have to put back the original stream. But things might get more complicated if tests are running in parallel.
This takes us to the next issue, the sleep. There isn't a strong guarantee to how long a sleep will block. This means your test would have to provide some buffer to ensure that the thread had time to write the String before checking the state of the mock stream. You don't want your test to be flaky because of some execution timing jitter. So you would have to decide what buffer you would consider acceptable.
An alternative approach would be to change the implementation of the code so that it is easier to test.
The simplest way to do this is to remove all the static dependencies. Instead of explicitly referencing System.out, the class could be initialized with with an PrintStream to write to. Additionally, you could define an interface that would wrap Thread.sleep(). For testing purposes, you can initialize the class with the mock stream and no-op implementation of the sleep interface. However, you may still have some timing issues as you need the newly created thread to execute before continuing the test.
The other thing you can do is take a step back and decide how much you care about this code being tested. There are only 4 interesting lines of code in this sample and none of them are complicated. Having a code review could be sufficient to ensure there are no bugs.
However, if the business logic is more complicate than writing to standard out, you might decided that testing that is important. The good news is that scheduling a task in an executor is straight forward and that is the part that is making the testing hard. You could make an abstraction that encompasses the scheduling of the task in a background thread. Then provide yourself with more direct access to the business logic in order to test that.
I have often solved that, by providing a ResultTarget which implements an interface IResultTarget to the thread,
In productive code the result will be a list that contains the calculation result. (or null)
In your unit test the ResultTarget is the unit test class itself, which then easily can check the received result.
public Interface IResultTarget {
List getResult();
}
public void ThreadTest extends TestCase implements IResultTarget {
List result;
public List getResult(
return this.result;
}
public void testThread() {
MyRunnable myRunnable= new MyRunnable ();
myRunnable.setResultTarget(this);
Thread thread = new Thread(myRunnable);
thread .start();
Thread.sleep(5 * 1000);
// expecting one element as result of the work of myRunnable.
assertEquals(1, result.size());
}
}
I want to execute a specific method which contains a service call. As it includes a service call , it will take some time for execution. I want to add a timer which will keep program in wait till that method completes its executiuon. Any work around for this?
You can organize an asynchroneous method execution with a timeout with java.util.concurrent package
ExecutorService executorService = ...
Object res = executorService.submit(new Callable<Object>() {
public Object call() throws Exception {
... your logic
}
}).get(timeout, TimeUnit.MILLISECONDS);
You can use a separate thread to call that service and using join() method of Thread class, you can force main program to wait until that thread finishes the execution.
Sheduler
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand(){
#Override
public void execute() {
// code here
}