Java - Future.get() multiple invocations - java

How does Java's Future.get() behave in the case where it is called multiple times after the task is completed?
Does it return the the same result? Or does throw an ExecutionException again and again with the same exception if the computation failed?
I can not find anything in the docs about it!

You can call get() on a Future as often as you like, and it will only block if the task that produces the result has not finished yet.
If the task has already finished, it will just immediately return the result of the task.
If the task has failed with an exception, calling get() will throw an ExecutionException each time you call it.

I can not find anything in the docs about it!
Have you read them ? because when I read them I got the Answer and here it is ....
V get()
throws InterruptedException,
ExecutionException
Waits if necessary for the computation to complete, and then retrieves
its result.
Returns:
the computed result
Throws:
CancellationException - if the computation was cancelled
ExecutionException - if the computation threw an exception
InterruptedException - if the current thread was interrupted while waiting
If Computation is not completed it will wait , and if it has already completed it will return result ASAP , no matter how many times you call it

Related

How to interrupt a thread submitted to newSingleThreadExecutor in Java/Scala?

Given that I have the following test-code:
import java.util.concurrent._
object TestTime {
def main(args: Array[String]) {
println("starting....")
val service = Executors.newSingleThreadExecutor
val r = new Callable[Unit]() {
override def call(): Unit = {
//your task
val t0 = System.nanoTime
val total = sum(1000000000)
val t1 = System.nanoTime
println("Elapsed time " + (t1 - t0) / 1e9 + " secs")
println(s"total = $total")
}
}
val f = service.submit(r)
try {
// attempt the task for 2 second
f.get(2, TimeUnit.SECONDS)
} catch {
case _: TimeoutException =>
f.cancel(true)
println(s"Timeout....")
} finally {
service.shutdown()
}
println("after 2 seconds....")
for(i <- 1 to 2){
println(s"$i ...")
Thread.sleep(1000)
}
println("main thread ends...")
}
//Given that sum() is written by others and I cannot change it.
def sum(k: Int): BigInt = {
var total: BigInt = 0
for (i <- 1 to k) {
total += i
}
total
}
}
I would like to execute the sum at most 2 seconds. If it exceeds the time limit, the corresponding thread should be interrupted immediately. To interrupt that thread, I have tried two methods when catch TimeoutException:
f.cancel(true)
service.shutdownNow()
However, according to my test, the above methods cannot interrupt the thread.
So I would like to know is there method to interrupt a thread compulsively.
According to JavaDocs for both Future#cancel and ExecutorService#shutdownNow, the typical implementation is that these methods result in interrupting the underlying thread.
If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
Note particuarly the last comment. Thread interruption via the Thread#interrupt method is a cooperative process. When one thread interrupts another, it results in setting the target thread's interrupted status. Also, if the target thread is blocked in certain specific methods, then that thread will experience an InterruptedException.
If the code executing in the target thread neither checks for interrupted status periodically via the Thread#isInterrupted method nor calls a blocking method and handles InterruptedException, then interruption effectively does nothing. That code is not cooperating in the interruption process, so there is effectively no way to shut it down, despite thread interruption.
//Given that sum() is written by others and I cannot change it.
Ideally, long-running code intended for execution in background threads would be changed to cooperate in the thread interruption. In your example, a viable technique would be to change sum to check Thread#isInterrupted every N iterations of the for loop, and if interrupted, abort the loop. Then, it could either throw an exception to indicate that it didn't complete or possibly return some sentinel BigInt value to indicate the abort if that's appropriate.
If the invoked code truly cannot be changed, then you cannot halt it by thread interruption. You could potentially use daemon threads so that at least these threads won't block JVM exit during shutdown.

Why does ExecutorService.invokeAll() return a List of Future?

invokeAll() doesn't return until all the Callables in the submitted Collection have completed, so what is the reason for making the results Futures?
Because the task might terminate normally or exceptionally, Futures can wrap the exception for you. For example,
Callable<Integer> c1 = () -> 1;
Callable<Integer> c2 = () -> {
throw new RuntimeException();
};
List<Future<Integer>> futures = executor.invokeAll(Arrays.asList(c1,c2));
for (Future<Integer> future : futures) {
System.out.println(future.get());
}
Note that because of Future, we were able to get a result of the future that terminated normally and the that terminated exceptionally.
If invokeAll returned a List<T>, it would have to return those that completed successfully and discarded those with exceptions.
Checking the ExecutorService#invokeAll Javadoc
Executes the given tasks, returning a list of Futures holding their
status and results when all complete. Future.isDone() is true for each
element of the returned list. Note that a completed task could have
terminated either normally or by throwing an exception. The results
of this method are undefined if the given collection is modified while
this operation is in progress.
Means that we're getting a list of Future objects because there may be situations where we do not get a value even if the task is complete.

How to make Callable wait till execution?

I have One Callable which I invoked using
FutureTask<Integer> task = new FutureTask<Integer>(new MyCallable(name, type));
pool = Executors.newSingleThreadExecutor();
pool.submit(task);
I want to know Is execution is continue after pool.submit(task) or It will wait for callable to complete its execution?
In short I just want to know is there any method like thread.join() for Callable?
... is there any method like thread.join() for Callable?
The pool.submit(callable) method returns a Future and will start executing immediately if the threads are available in the pool. To do a join, you can call future.get() which joins with the thread, returning the value returned by the call() method. It is important to note that get() may throw an ExecutionException if the call() method threw.
You do not need to wrap your Callable in a FutureTask. The thread-pool does that for you. So your code would be:
pool = Executors.newSingleThreadExecutor();
Future<String> future = pool.submit(new MyCallable(name, type));
// now you can do something in the foreground as your callable runs in the back
// when you are ready to get the background task's result you call get()
// get() waits for the callable to return with the value from call
// it also may throw an exception if the call() method threw
String value = future.get();
This is if your MyCallable implements Callable<String> of course. The Future<?> will match whatever type your Callable is.
task.get() (task being a FutureTask) expects the current thread to wait for the completion of the managed task by the thread pooler.
This method ends up returning either a concrete result or throwing the same checked exception (although wrapped into an ExecutionException) that the job thread would throw during its task.

Why does Thread.isInterrupted () always return false?

I found the method of JavaDoc:
Returns:
true if this thread has been interrupted; false otherwise.
I think something wrong with my understanding of the method. Further, I may misunderstand the concept ‘interrupt’ in Thread.
Any explanation is welcome! Thank you!
Code snippet:
In thread definition:
public void run() {
try {
//Do something
} catch (InterruptedException e) {
System.out.println(isInterrupted());//Always false
return;
}
}
invoke:
theThread.interrupt();
This behaviour is typically documented in methods that throw that exception. For example, the javadoc for Object.wait() says:
"InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown."
Indeed, the javadoc for the exception itself says this:
"Occasionally a method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception. The following code can be used to achieve this effect:
if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();
Note how they emphasize that the flag should be cleared before the exception is thrown.
Why was it designed to work like this? You'd have to ask the designers, but I expect they figured that an exception handler should handle the situation, and that there should therefore be no need for the flag to still be set at that point. (If the handler doesn't fully handle the situation it can either rethrow the exception, or call Thread.getCurrentThread.interrupt() to set the flag again.)
Once the exception is thrown, the thread is no longer in an interrupted state.
Adding to cdhowie's answer, one standard pattern is to let the Thread handle interruption. This is useful with Executors, when the running code doesn't "own" the Thread and should not get in the way of interruption (unless you really know what you're doing)
public void run() {
try {
//Do something
} catch (InterruptedException e) {
// Do whatever local clean up you need to
...
// Then let the owning Thread know it's been interrupted, so it too can clean up
Thread.currentThread().interrupt(); //
}
}
You would check isInterrupted() in your own code, for example from a loop. If the thread has been interrupted you can then throw InterruptedException to stop executing.
In your example if you caught InterruptedException you can be sure that it was interrupted and you don't have to check that method.

Exception in a Thread

I have made a multi-threading program. In it, the main thread starts 10 threads but the problem is whenever an exception occured in one of the threads, the whole application gets stopped.
But I want that whenever an exception occurred in one thread, only that thread should gets stopped and other threads keep working. How can I do that?
Second, I want that the main thread should stopped only after all the 10 threads finished. How can I do that?
You could use an ExecutorService (containing multiple threads) to process your individual items of work by calling submit(). The submit method returns a Future, which will encapsulate either the result of the processing or any exception thrown. In other words, the threads within your ExecutorService will not terminate if an exception occurs.
Example
First create an executor service containing more than one thread:
ExecutorService execService = Executors.newFixedThreadPool(5);
Define the item of work we wish to submit as a Callable:
public class MyWorkItem implements Callable<Integer> {
public Integer call() throws Exception {
int result = new Random().nextInt(5);
// Randomly fail.
if (result == 0) {
throw new IllegalArgumentException("Fail!");
}
return result;
}
}
Submit some work for the executor service to do, and store the Future<Integer> for each Callable<Integer>.
List<Future<Integer>> futures = new LinkedList<Future<Integer>>();
for (int i=0; i<10; ++i) {
futures.add(execService.submit(new MyWorkItem()));
}
Now iterate over the futures attempting to retrieve the result of each work item (we could use a CompletionService for this).
for (Future<Integer> future : futures) {
try {
Integer result = future.get();
} catch(Exception ex) {
// Handle exception.
}
}
At the end of your main method you should call join on every started thread.
By the way: If you want to handle the exceptions of your threads, you can use Thread.setDefaultUncaughtExceptionHandler()
Surround with try/catch all
public void run() {
try {
....
} catch( Exception e ){}
}
Although I would better try to identify the reasons for those exceptions.
For #1, if this is your intended goal you should consider how you are handling that exception and what types of exceptions your are expecting. If these are application faults you can determine a more useful way to catch the exception at the individual thread level and feed and important information back to the parent thread. Alternatively a solution for managing the thread pool for you may be a better method to go with as #Adamski pointed out, like the implementation of the ExecutorSerivce ThreadPoolExecutor, however you will need to understand the exceptions and if they can be prevented with some additional logic if not then having a better way to manage your jobs effectively is the way to go.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
For #2, join() or use a Thread pool to manage them.
Concerning your first point I would suggest that you gracefully exit a thread when an exception is thrown, that is, catch it within the thread (and not let it bubble up to the jvm).

Categories

Resources