I have a custom asynchronous method and I know threads are executed randomly, but I want to execute them in order.
I want to solve the problem in the main()
method.
I've tried Thread.sleep()
but it's not useful.
public static void main(String[] args) throws Exception{
Monster monster = new Monster();
System.out.println(1);
monster.exe();
System.out.println(2);
monster.exe();
System.out.println(3);
monster.exe();
System.out.println(4);
}
Class Monster
class Monster {
public void exe() {
new Thread(() -> {
System.out.println("Monster...: " Thread.currentThread().getName());
}).start();
}
}
CodePudding user response:
That's doable, but frankly pointless because such a "parallel" execution even less performant than sequential processing of these tasks.
If you are doing that just as an exercise, that's OK. Otherwise, either don't try to control the execution of these tasks or do it in a single-threaded environment.
For that, you might use method join()
:
public static void main(String[] args) throws InterruptedException {
Monster monster = new Monster();
System.out.println(1);
Thread thread1 = monster.exe();
thread1.join();
System.out.println(2);
Thread thread2 = monster.exe();
thread2.join();
System.out.println(3);
Thread thread3 = monster.exe();
thread3.join();
System.out.println(4);
}
Each call of join()
will block the main thread until another thread (on which this method was invoked) isn't finished its job.
Note: method join()
throws InterruptedException
which is a checked exception and must be either handled with a try/catch
or to be signified in the method declaration. I've deliberately chosen the second option in order to make the code simpler and keep focus on what it is intended to do. But you should know that it's not a good practice to add the throws
clause to the declaration of the main()
method.
A small change was done to the Monster
class (method exe()
returns a thread that has been created in order to be able to join on it).
public class Monster {
public Thread exe() {
Thread thread = new Thread(() -> {
System.out.println("Monster...: " Thread.currentThread().getName());
});
thread.start();
return thread;
}
}
Output
1
Monster...: Thread-0
2
Monster...: Thread-1
3
Monster...: Thread-2
4
CodePudding user response:
Another way to do it is to extract the codes that you want to execute asynchronously into a separate Runnable
:
Runnable newMonstorTask() {
return ()->System.out.println("Monster...: " Thread.currentThread().getName());
}
And then use CompletableFuture
to configure them to execute in order and asynchronously :
CompletableFuture.runAsync(newMonstorTask())
.thenRunAsync(newMonstorTask())
.thenRunAsync(newMonstorTask())
.thenRunAsync(newMonstorTask());
CodePudding user response:
You can use CompletableFuture
and then methods like thenApply()
.
Please look here: https://www.deadcoderising.com/java8-writing-asynchronous-code-with-completablefuture/