How to asynchronously call a method in Java
Solution 1
I just discovered that there is a cleaner way to do your
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(At least in Java 8), you can use a lambda expression to shorten it to:
new Thread(() -> {
//Do whatever
}).start();
As simple as making a function in JS!
Solution 2
Java 8 introduced CompletableFuture available in package java.util.concurrent.CompletableFuture, can be used to make a asynch call :
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});
Solution 3
You may wish to also consider the class java.util.concurrent.FutureTask
.
If you are using Java 5 or later, FutureTask is a turnkey implementation of "A cancellable asynchronous computation."
There are even richer asynchronous execution scheduling behaviors available in the java.util.concurrent
package (for example, ScheduledExecutorService
), but FutureTask
may have all the functionality you require.
I would even go so far as to say that it is no longer advisable to use the first code pattern you gave as an example ever since FutureTask
became available. (Assuming you are on Java 5 or later.)
Solution 4
i don't like the idea of using Reflection for that.
Not only dangerous for missing it in some refactoring, but it can also be denied by SecurityManager
.
FutureTask
is a good option as the other options from the java.util.concurrent package.
My favorite for simple tasks:
Executors.newSingleThreadExecutor().submit(task);
little bit shorter than creating a Thread (task is a Callable or a Runnable)
Solution 5
You can use the Java8 syntax for CompletableFuture, this way you can perform additional async computations based on the result from calling an async function.
for example:
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
More details can be found in this article
Related videos on Youtube
Felipe Hummel
Updated on March 20, 2021Comments
-
Felipe Hummel about 3 years
I've been looking at Go's goroutines lately and thought it would be nice to have something similar in Java. As far as I've searched the common way to parallelize a method call is to do something like:
final String x = "somethingelse"; new Thread(new Runnable() { public void run() { x.matches("something"); } }).start();
Thats not very elegant. Is there a better way of doing this? I needed such a solution in a project so I decided to implement my own wrapper class around a async method call.
I published my wrapper class in J-Go. But I don't know if it is a good solution. The usage is simple:
SampleClass obj = ... FutureResult<Integer> res = ... Go go = new Go(obj); go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter //... Do something else //... System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
or less verbose:
Go.with(obj).callLater("myRandomMethod"); //... Go away if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended System.out.println("Method is finished!");
Internally I'm using a class that implements Runnable and do some Reflection work to get the correct method object and invoking it.
I want some opinion about my tiny library and on the subject of making async method calls like this in Java. Is it safe? Is there already a simplier way?
-
msangel over 10 yearsCan you show your code of J-Go lib again?
-
Amit Kumar Gupta about 8 yearsI was working on a project where I was reading a stream char wise. Once a complete word is read I was performing many operations on that word. Finally I put it into a collection. Once the all data from the stream is read I return the response. I decided to start thread for each time I perform operation on a word. But it decreased the overall performance. Then I got to know that threads are in itself are an expensive operation. I am not sure if starting a thread to call a method concurrently can give any performance add until it is performing any heavy IO operation.
-
TriCore over 6 yearsGreat question!! Java 8 provides CompletableFutures for this. Other answers are based on probably old versions of Java
-
-
Felipe Hummel over 14 yearsThe thing is I just want to execute one method call. This way I would have to change the implementation of the target class. The thing I wanted is exactly call without having to worry about impĺementing Runnable or Callable
-
Felipe Hummel over 14 yearsThe thing is I just want to execute one method call. This way I would have to change the implementation of the target class. The thing I wanted is exactly call without having to worry about impĺementing Runnable or Callable
-
shadit over 14 yearsI hear you. Java does not (yet) have first-class functions, so this is the state of the art right now.
-
user85421 over 14 yearsthen this would'nt help much :( but normally I would prefer using a Runnable or Callable instead of Reflection
-
gumuruh almost 12 yearsthanks for the 'future' keywords... now I'm opening the tutorials about them... very useful. :D
-
Daniel Szalay almost 12 yearsJust a short note: It's nicer to keep track of the
ExecutorService
instance, so you can callshutdown()
when you have to. -
MikeFHay almost 11 years-1 as far as I can tell, FutureTask by itself is not sufficient to run anything asynchronously. You still need to create a Thread or Executor to run it, as in Carlos' example.
-
Deckard over 9 yearsYour answer helped my problem - stackoverflow.com/questions/27009448/…. Little tricky to apply my situatioin, but worked it out eventually :)
-
bmorin over 8 yearsNote that this approach would make all calls to save asynchronous, which might or might not be what we want. In cases when only some calls to a given method should be made async, other approaches suggested on this page can be used.
-
Giovanni Toraldo over 8 yearsif you are using spring-boot.
-
Mukti over 7 yearsIt's really nice to use this using Java 8.
-
yatanadam over 7 yearsHow to call with parameters ?
-
user3004449 about 7 years@yatanadam This may answer your question. Just place the above code inside a method and pas the variable like you would normally do. Check out this test code I made for you.
-
user3004449 about 7 years@eNnillaMS Does the thread has to be stopped after running? Does it stop automatically, or by the garbage collector?
-
Naman almost 7 yearsCan I use it in a web application (since managing threads is not recommended there) ?
-
djangofan over 6 yearsIf you did this, wouldn't you possibly end up with un-closed ExecutorService , causing your JVM to refuse to shutdown? I would recommend writing your own method to get a single-threaded, time-limited, ExecutorService .
-
ndm13 over 6 years
CompletableFuture
was mentioned in another answer, but that one used the wholesupplyAsync(...)
chain. This is a simple wrapper that fits the question perfectly. -
Shawn almost 6 years@user3004449 The thread stops automatically, however, you can force it as well.
-
Mark Jeronimus over 5 years
ForkJoinPool.commonPool().execute()
has slightly less overhead -
mrtechmaker over 5 years@Deckard - how was this tricky for you? I am asking as I have the exact same question as you have asked in your link.
-
Amit Upadhyay over 3 years@AegisHexad for an application this will spawn as many threads as possible, which will impact the memory hence it might increase the latency, if there is a very small task to execute within thread then this would work, but if we are performing some blocking operation(network calls, etc), then multiple threads being spawned can choke up the app, right?