Java.util.concurrent.Future.get () is not returned

I have the following Java code:

final Future future = exeService.submit( new Runnable() { public void run() { myObject.doSomething(); } } ); future.get(); 

where exeService is an instance

 java.util.concurrent.ExecutorService 

The problem is that myObject.doSomething() never returns, and therefore future.get() never returns.

However, if I replaced the call with submit execute call as follows:

 exeService.execute( new Runnable() { public void run() { myObject.doSomething(); } } ); 

a call to myObject.doSomething() returned. I don't know if this matters, but doSomething() is the void method.

Why doSomething() end when using execute , but not when using submit ?

In addition, I do not need to use future.get() ; which seemed like the most natural way to do this. (I also encounter the same problem with CountdownLatch .) The fact is that I need to wait until doSomething() before continuing, and for complex reasons I will not go into it here, I need to run it on a separate thread. If there is another way to do this, it will be fine.

+4
source share
4 answers

Like in Executor.execute () Javadoc :

Executes a given command at some time in the future. A team can execute in a new thread in a combined thread, or in an implementation that is at the discretion of the Contractor.

Thus, the execute() method returns immediately, leaving you with no option to request the status of the submitted task.

On the other hand, ExecutorService.submit () :

Submits the Runnable task for execution and returns a future representing the task. The Future get method will return null after successful completion.

Future.get () will return only after a successful competition, so never in your case.

The document Future.get () states the following:

Expects, if necessary, to calculate to complete, and then the result.

+15
source

I created SSCCE :

 package com.stackoverflow.q2585971; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Test { public static void main(String args[]) throws Exception { ExecutorService executor = Executors.newCachedThreadPool(); Future<?> future = executor.submit( new Runnable() { public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Epic fail."); } } } ); System.out.println("Waiting for task to finish.."); future.get(); System.out.println("Task finished!"); executor.shutdown(); } } 

It works great. First he prints

  Waiting for task to finish .. 

then in one second you will see

  Task finished! 

So your problem lies somewhere else. I will duplicate my comment on your question here:

Your question is rather confusing. The first design should work. Confusion in the "return". Don't you mean completion or fulfillment? Your confusion seems to be based on the fact that future.get() actually waiting for completion to complete and thus will block the thread and prevent it from executing the rest of the code after the future.get() .

+7
source

Java futures are blocked! get(). This method blocks the current thread until a future instance completes its work, thus requiring the use of one thread more than the work that must be performed just to manage what happens when it is done

+1
source

Check for a dead end in doSomething .

I would start by looking for wait calls.

If you wait for something, you need to tell the object you expect from another thread by calling notify or notifyAll .

0
source

Source: https://habr.com/ru/post/1306135/


All Articles