How to asynchronously call a method in Java

363,590

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

Share:
363,590

Related videos on Youtube

Felipe Hummel
Author by

Felipe Hummel

Updated on March 20, 2021

Comments

  • Felipe Hummel
    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
      msangel over 10 years
      Can you show your code of J-Go lib again?
    • Amit Kumar Gupta
      Amit Kumar Gupta about 8 years
      I 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
      TriCore over 6 years
      Great question!! Java 8 provides CompletableFutures for this. Other answers are based on probably old versions of Java
  • Felipe Hummel
    Felipe Hummel over 14 years
    The 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
    Felipe Hummel over 14 years
    The 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
    shadit over 14 years
    I hear you. Java does not (yet) have first-class functions, so this is the state of the art right now.
  • user85421
    user85421 over 14 years
    then this would'nt help much :( but normally I would prefer using a Runnable or Callable instead of Reflection
  • gumuruh
    gumuruh almost 12 years
    thanks for the 'future' keywords... now I'm opening the tutorials about them... very useful. :D
  • Daniel Szalay
    Daniel Szalay almost 12 years
    Just a short note: It's nicer to keep track of the ExecutorService instance, so you can call shutdown() when you have to.
  • MikeFHay
    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
    Deckard over 9 years
    Your answer helped my problem - stackoverflow.com/questions/27009448/…. Little tricky to apply my situatioin, but worked it out eventually :)
  • bmorin
    bmorin over 8 years
    Note 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
    Giovanni Toraldo over 8 years
    if you are using spring-boot.
  • Mukti
    Mukti over 7 years
    It's really nice to use this using Java 8.
  • yatanadam
    yatanadam over 7 years
    How to call with parameters ?
  • user3004449
    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
    user3004449 about 7 years
    @eNnillaMS Does the thread has to be stopped after running? Does it stop automatically, or by the garbage collector?
  • Naman
    Naman almost 7 years
    Can I use it in a web application (since managing threads is not recommended there) ?
  • djangofan
    djangofan over 6 years
    If 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
    ndm13 over 6 years
    CompletableFuture was mentioned in another answer, but that one used the whole supplyAsync(...) chain. This is a simple wrapper that fits the question perfectly.
  • Shawn
    Shawn almost 6 years
    @user3004449 The thread stops automatically, however, you can force it as well.
  • Mark Jeronimus
    Mark Jeronimus over 5 years
    ForkJoinPool.commonPool().execute() has slightly less overhead
  • mrtechmaker
    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
    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?