How does one implement a truly asynchronous java thread
Asked Answered
E

7

22

I have a function that needs to perfom two operations, one which finishes fast and one which takes a long time to run. I want to be able to delegate the long running operation to a thread and I dont care when the thread finishes, but the threads needs to complete. I implemented this as shown below , but, my secondoperation never gets done as the function exits after the start() call. How I can ensure that the function returns but the second operation thread finishes its execution as well and is not dependent on the parent thread ?

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 
Erythroblast answered 20/4, 2010 at 16:8 Comment(3)
You never use SecondOperation in your someFunction(), how do you expect it to run?Burlburlap
you're even missing a semicolon :-/Macey
Sorry, fixed the bug in my code.Erythroblast
N
48
public void someFunction(final String data) {
    shortOperation(data);
    new Thread(new Runnable() {
        public void run(){
            longOperation(data);
        }
    }).start();
}

If someFunction is called, the JVM will run the longOperation if

  1. the thread running it is not marked as a daemon (in the above code it is not)
  2. the longOperation() does not throw an exception and
  3. no calls to System.exit() is made in longOperation()
Narbada answered 20/4, 2010 at 16:58 Comment(0)
B
1

IF your second function is not getting done it has nothing to do with your function returning. If something calls System.exit() or if your function throws an exception, then the thread will stop. Otherwise, it will run until it is complete, even if your main thread stops. That can be prevented by setting the new thread to be a daemon, but you are not doing that here.

Broiler answered 20/4, 2010 at 16:11 Comment(1)
Just to be clear, setting it to a daemon will cause the JVM to exit before it is finished if no other non-daemon threads are running. So it is the opposite of what you want. You set it by calling setDaemon(true) on the Thread object before calling start().Broiler
R
1

Start of Java 1.8 you can run async code very simply. See you next code:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Semaphore;

public class HelloWorld {
  public static void main(String[] args) {
    CompletableFuture<String> future = CompletableFuture.supplyAsync(()->
      //run the code async        
      "result"
    );
    String result = future.join(); //wait async result
    System.out.println(result);
  }
}
Radiochemical answered 3/2, 2021 at 14:55 Comment(1)
One important side note, given most default implementations of CompleteableFuture.cancel method, you will never be able to interrupt that async thread.Amplification
T
0

The JVM will not exit before the thread terminates. This code that you posted does not even compile; perhaps the problem is in your actual code.

Trager answered 20/4, 2010 at 16:11 Comment(1)
I don't have any idea what you mean by "the logical part", but the code that you have provided is not the part that is causing your thread to terminate.Trager
M
0

It may be late to answer this question, but here is the working solution. Just add the runnables to ExecutorService.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

ExecutorService executor = Executors.newFixedThreadPool(10);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                //your code
            }
        });
Moonset answered 19/4, 2019 at 7:11 Comment(0)
M
0

if i get your question right , you wanna invoke someFunction() , execute the short smallOperation() , run a thread to the SecondOperation and make sure that when returned from this function , the SecondOperation is completed .

if the flow i suggested is correct , u only need to add the following line :

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
   th.join(); //add this line to make your MainThread await for this to finish . 
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 

take a look at this article , it states that "When we invoke the join() method on a thread, the calling thread goes into a waiting state. It remains in a waiting state until the referenced thread terminates" . which i think what you trying to accomplish

if its not the case and you wanna be notified when the SecondOperation terminates , i suggest you use asyncTask

Minivet answered 4/9, 2019 at 12:18 Comment(0)
O
-1

Solution using modern Java

public void someFunction(String data) {
    smallOperation();
    new Thread(() -> {
        // doSomething long running
    }).start();
}
Opine answered 21/12, 2018 at 15:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.