Future.get() does not return - java

I have the following piece of code:
public class Test {
List<Future> future = new ArrayList<Future>();
public static void main(String args[]) throws Exception {
Adapter b1 = new Adapter();
final ExecutorService threadPool = Executors.newCachedThreadPool();
for(//iterate for number of files) {
while(data exists in file) {
//Call a function to process and update values in db
future.add(threadPool.submit(new Xyz(b1)));
//read next set of data in file;
}
}
try {
for(Future f: future) {
f.get();
}
}
catch(Exception e) {
throw e;
}
}
}
class Xyz implements Runnable {
private Adapter a1;
public Xyz(Adapter al) {
this.a1=a1;
}
#Override
public void run() {
try {
a1.abc();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
When the number of files is 1 (for loop runs for 1 time), the code runs fine.
But, when the number of files increases, the code never returns back from future.get() method.

just out of curiosity.. do i need to shutdown the executor somewhere ??
Yes, and this is likely the problem. Each Future.get() will block until the corresponding task is complete, then once all the tasks are complete your main thread will exit. But your java process will not exit because the thread pool threads are still active in the background. You should shut down the executor once you have finished with it, most likely as the last thing in your main method.
I also note that you're submitting many tasks that wrap the same Adapter instance and all call its abc() method - check that there's nothing in there that will deadlock when called simultaneously in more than one thread.

Your Callable::call / Runable::run does not return. Otherwise the corresponding future would not block.
Additional executor.shutdown or future.cancel will thow an InterruptedException to stop the thread processing the object you submitted but it is up to you if to catch it or not. Your are responsible for making the jobs you submitted stop.
When you submit thousands Callables/Runnables to a CachedExecutor that it might spawn so many threads that your machine gets so slow that you think it takes forever. But you would have noticed that.
When dealing with an undefined number of parallelizable tasks i suggest to use a FixedThreadPool with not much more threads that there are cpu cores.
Edit: Therefore when you set a breakpoints at a1.abc(); and step forward you will probably find out that it never returns.

Related

Java timeout function is not working for my below codes

I tried to set a 1-second time limit for my SQL query in Java, using the methods:
How to timeout a thread
public class App {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(1, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
#Override
public String call() throws Exception {
try {
// some codes to do query via SQL Server JDBC, assuming it takes 10 seconds.
ResultSet result = statement.executeQuery();
// some codes to print the query result
return "Done";
}
catch (Exception e) {
System.out.println();
e.printStackTrace();
}
}
}
However, I found that though it prints 'Terminated' after 1 second, the program keeps running and prints the query result after 10 seconds. What's the reason why it doesn't work and how to fix it?
shutdownNow doesn't actually stop a thread, it merely sends a signal (an interrupt) that the Thread can act upon. Stopping a Thread in Java is tricky because while you can just kil the thread (with Thread.stop), you really shouldn't because you have no idea what state the Thread is in and what it will leave behind.
You can find more information in the documentation.
Calling cancel on a future does not guarantee that the job will be cancelled. It depends on the method checking periodically for interrupts, and then aborting if an interrupt is detected. Statement.execute() does not do that.
In your case, given you are executing a SQL statement, there is a method in the Statement class (setQueryTimeout) which achieves what you appear to be after without over-engineering timeouts by other means.
Another way you can approach this is by using the thread.sleep() method. I often use it when I want my program to simply pause for a short or long period of time. In the parameters, you put values in thousands that correspond to seconds. For example:
public static void main(String[] args) throws InterruptedException // Required for thread.sleep()
{
System.out.println("Hi there.");
Thread.sleep(2000); // Wait two seconds before running the next line of code
System.out.println("Goodbye.");
}
This is quite basic, but can be used for more than just strings. Hope this helps.

HealthChecker for Java Process

I want to create a health checker, which will check the health of a java process. My process does a lot of things and is multi threaded. Various exceptions could be thrown, like Service / SQL / IO, etc. My plan is to call the HealthChecker to check for the process, from the catch block, in the individual threads. This will check for all the different healths, and in the case where there is any issue it will pause the threads, and log appropriately. There will be other processes which will read the logs by the process, and alert support to take appropriate actions.
Below is the general structure of the java process.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
while(true){
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers());
}
}
}
}
class Workers implements Runnable{
#Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
try{
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
class HealthChecker{
public static void checkHealth() {
//Check health and then , log and pause all the threads
}
}
I am not able to figure out a way to pause all the threads. If there is a db exception I want all the threads to pause. I am requesting some suggestions.
You need a way to block the threads until some event occurs that allows the threads to continue. I see some major issues with the code:
1) The while(true) in your main thread might lead to a StackOverflowError. With each iteration of the while loop, you will add 10 more threads to the executor, and this will just continue unbounded.
2) There is no loop in your run() so that even if an exception is caught and we wait for the HealthCheck, the run() method would still exit. While a loop is not needed in your run() if you can constantly execute new Threads from your main thread to take the place of the terminated one, but that logic is not presently there in the main loop.
But setting those concerns aside here is one way to block worker threads until some event (presumably a HealthCheck all clear) occurs.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
HealtchChecker hChecker = new HealthChecker();
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers(hChecker));
}
}
}
class Workers implements Runnable{
private HealtchChecker hChecker;
public Workers(HealtchChecker hChecker){
this.hChecker = hChecker;
}
#Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
while(true) {
try{
}catch (InterruptedException ie) {
throw ie;
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
}
class HealthChecker implements Runnable {
private final Semaphore semaphore = new Semaphore(1, true);
public void checkHealth() {
try {
semaphore.acquire();
} finally {
semaphore.release();
}
}
#Override
public void run(){
//code to check for errors that cause threads to pause.
if (inErrorState) {
semaphore.acquire();
} else {
semaphore.release();
}
}
}
A few things worth mentioning.
1) The main thread only creates 10 threads, versus an unbounded amount. You can adjust this as needed.
2) The Worker thread is long lived, meaning it will continue running even if it encounters Exceptions, except for an InterruptException.
3) HealthCheck is no longer a static object. it is instead a shared object.
4) HealthCheck is a runnable that can be executed in its own thread for monitoring for errors. I did not add the code to execute this thread.
5) HealCheck uses a Semaphore to cause the threads to block until the error state is cleared. I looked for other objects that can do this, like CountDownLatch or CyclicBarrier or Phaser, but this one came closest to giving us what we need to block all the threads from one point (the run() method).
Its not perfect but I think it gets you a little bit closer to what you want.
You're venturing pretty far afield from best practices, but you didn't ask about best practices for monitoring the health of threads - so I won't answer that question. Instead, I'll just answer the question you asked: how can I pause a set of threads managed by an ExecutorService?
Assuming that your Workers.run() will eventually end without intervention (in other words, it's not in an infinite loop - intentional or otherwise), the right thing to do is to call service.shutdown() (where service is your instance of ExecutorService). To do this, you can pass service in to HealthCheck.healthCheck() as a new parameter. Calling shutdown() will allow the currently-running threads to complete, then stop the executor.
If Workers.run() will not naturally complete, best practice says that you need to change your code such that it will. There is a Thread.stop() method you can call to halt the thread and a Thread.suspend() method you can call to suspend the thread. Both of these are double-bad ideas for you to use for two reasons:
They are Deprecated and will leave the Threads in a super-unhealthy state. You will have very difficult problems in the future if you use them.
You are using ExecutorService. That means you are delegating thread management to that class. If you go messing with the state of the Threads underneath ExecutorService, it can't manage the thread pool for you and, again, you will have very difficult problems in the future.

How to run concurrent job with dependent tasks?

I have a situation that I need to work on
I have a class which has send method, example
#Singleton
class SendReport {
public void send() {}
}
The send method is called from a user click on web page, and must return immediately, but must start a sequence of tasks that will take time
send
->|
| |-> Task1
<-| |
<-|
|
|-> Task2 (can only start when Task1 completes/throws exception)
<-|
|
|-> Task3 (can only start when Task2 completes/throws exception)
<-|
I am new to Java concurrent world and was reading about it. As per my understanding, I need a Executor Service and submit() a job(Task1) to process and get the Future back to continue.
Am I correct?
The difficult part for me to understand and design is
- How and where to handle exceptions by any such task?
- As far as I see, do I have to do something like?
ExecutorService executorService = Executors.newFixedThreadPool(1);
Future futureTask1 = executorService.submit(new Callable(){
public Object call() throws Exception {
System.out.println("doing Task1");
return "Task1 Result";
}
});
if (futureTask1.get() != null) {
Future futureTask2 = executorService.submit(new Callable(){
public Object call() throws Exception {
System.out.println("doing Task2");
return "Task2 Result";
}
}
... and so on for Task 3
Is it correct?
if yes, is there a better recommended way?
Thanks
Dependent task execution is made easy with Dexecutor
Disclaimer : I am the owner
Here is an example, it can run the following complex graph very easily, you can refer this for more details
Here is an example
If you just have a line of tasks that need to be called on completion of the previous one than as stated and discussed in the previous answers I don't think you need multiple threads at all.
If you have a pool of tasks and some of them needs to know the outcome of another task while others don't care you can then come up with a dependent callable implementation.
public class DependentCallable implements Callable {
private final String name;
private final Future pre;
public DependentCallable(String name, Future pre) {
this.name = name;
this.pre = pre;
}
#Override
public Object call() throws Exception {
if (pre != null) {
pre.get();
//pre.get(10, TimeUnit.SECONDS);
}
System.out.println(name);
return name;
}
A few other things you need to take care of based on the code in your question, get rid of future.gets in between submits as stated in previous replies. Use a thread pool size of which is at least greater than the depth of dependencies between callables.
Your current approach will not work as it will block till the total completion which you wanted to avoid.
future.get() is blocking();
so after submitting first Task, your code will wait till its finished and then next task will be submitted, again wait, so there is no advantage over single thread executing the tasks one by one.
so if anything the code would need to be:
Future futureTask2 = executorService.submit(new Callable(){
public Object call() throws Exception {
futureTask1.get()
System.out.println("doing Task2");
return "Task2 Result";
}
}
your graph suggests that the subsequent task should execute despite exceptions. The ExecutionException will be thrown from get if there was problem with computation so you need to guard the get() with appropriate try.
Since Task1, Task2 have to completed one after another, why you do you want them exececuted in different threads. Why not have one thread with run method that deals with Task1,Task2.. one by one. As you said not your "main" thread, it can be in the executor job but one that handles all the tasks.
I personally don't like anonymous inner classes and callback (that is what you kind of mimic with chain of futures). If I would have to implement sequence of tasks I would actually implement queue of tasks and processors that executes them.
Mainly cause it is "more manageable", as I could monitor the content of the queue or even remove not necessary tasks.
So I would have a BlockingQueue<JobDescription> into which I would submit the JobDescription containing all the data necessary for the Task execution.
I would implement threads (Processors) that in their run() will have infinitive loop in which they take the job from the queue, do the task, and put back into the queue the following task. Something in those lines.
But if the Tasks are predefined at the send method, I would simply have them submitted as one job and then execute in one thread. If they are always sequential then there is no point in splitting them between different threads.
You need to add one more task if you want to return send request immediately. Please check the following example. It submits the request to the background thread which will execute the tasks sequentially and then returns.
Callable Objects for 3 long running tasks.
public class Task1 implements Callable<String> {
public String call() throws Exception {
Thread.sleep(5000);
System.out.println("Executing Task1...");
return Thread.currentThread().getName();
}
}
public class Task2 implements Callable<String> {
public String call() throws Exception {
Thread.sleep(5000);
System.out.println("Executing Task2...");
return Thread.currentThread().getName();
}
}
public class Task3 implements Callable<String> {
public String call() throws Exception {
Thread.sleep(5000);
System.out.println("Executing Task3...");
return Thread.currentThread().getName();
}
}
Main method that gets request from the client and returns immediately, and then starts executing tasks sequentially.
public class ThreadTest {
public static void main(String[] args) {
final ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.submit(new Runnable() {
public void run() {
try {
Future<String> result1 = executorService.submit(new Task1());
if (result1.get() != null) {
Future<String> result2 = executorService.submit(new Task2());
if (result2.get() != null) {
executorService.submit(new Task3());
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
});
System.out.println("Submitted request...");
}
}

How to be notified when thread goes down?

In java, I have ExecutorService that runs with while true, and Throwable catch clouse. I find out that from time to time the thread goes down. That means the system stop function.
So my question is, first of all, how can I catch the "thread killed" event (in order to send me email on such case)?
Also, how can this thread goes down?
the code is:
ExecutorService changesTrackerThread = Executors.newSingleThreadExecutor();
changesTrackerThread.submit(queueUpdater());
private Runnable queueUpdater() {
return new Runnable() {
#Override
public void run() {
while (true)
{
try
{
// do some code, then sleep
Thread.sleep(2000L);
} catch (Throwable t)
{
_log.error("something bad happened, but the loop should keep running", t);
}
}
}
};
Well first of all, why are you using a while loop here!?
You should use a scheduled executor:
ExecutorService changesTrackerThread = Executors.newSingleThreadScheduledExecutor()();
changesTrackerThread.scheduleAtFixedRate(new queueUpdater(), 0, 2, TimeUnit.SECONDS);
private Runnable queueUpdater() {
return new Runnable() {
#Override
public void run() {
try
{
// do some code
} catch (Throwable t)
{
_log.error("something bad happened", t);
}
}
};
I do not know why your thread dies, show us the full code.
But this way even if the thread dies the Excecutor will rerun it after the given period(2 seconds in this example.
As others have noted, you could replace your while (true) and sleep() loop with a ScheduledExecutorService. Scheduling a repeating task on such a service will return a ScheduledFuture which you can use to check the status of this task or to cancel it if you have a need for that. This will enable you to remove the try/catch block from the code.
Start the service like this:
ScheduledExecutorService svc = Executors.newScheduledThreadPool(1);
I would use newScheduledThreadPool() instead of newSingleThreadScheduledExecutor() since the former will restart threads if necessary.
Then, schedule the work like this:
void doSomeCode() {
// do some code
}
ScheduledFuture<?> sf = svc.scheduleAtFixedRate(this::doSomeCode, 0L, 2L, TimeUnit.SECONDS);
(Or if you wish you can inline doSomeCode() as a lambda or an anonymous inner class.)
Now what happens if the task fails with an exception? The ScheduledFuture object returned allows you to check status in a variety of ways. If you have a thread that you can dedicate to waiting for failures, you can have it call sf.get() which will throw an ExecutionException that wraps the exception that caused the task to fail. Otherwise, it blocks indefinitely. ScheduledFuture.get() is a bit weird in that unlike an ordinary Future.get() call, it never returns a value; it always throws an exception.
When/if the task fails, the caller of sf.get() can log the exception and resubmit the task, or whatever. If you don't want to block a thread indefinitely, you can poll for failure using sf.isDone() or sf.get(0L, TimeUnit.SECONDS). Note that both overloads of sf.get() communicate all of their return information via the type of a thrown exception, which may make them somewhat inconvenient to use.
You could put exception handling within the task itself, catching Throwable and continuing no matter what, and this will probably work. It does bake the logging/restart/resubmission policy into the task itself, which may be unpleasant. Using ScheduledFuture lets you separate these policies from the actual work performed by the task.

Get exception from threads in java

I have a question with my code.
I have two threads running from the main method & I want to catch the exception that can occur in any of the two threads in the main method.
Future<Object> incoming=Executors.newSingleThreadExecutor().submit(new Task1(param1));
Future<Object> outgoing=Executors.newSingleThreadExecutor().submit(new Task2(param2));
Problem is that if i use Future Object & call get() method for the exception, it will block my code & i would not know if say thread 2 has finished/throws exception before thread 1.
How can i handle this elegantly instead of this?
while(!(incoming.isDone() || outgoing.isDone())){}
I would process the exception asynchronously if you want to deal with as soon as it happens and not wait for any other tasks to finish.
ExecutorService oneService = ...
oneService.submit(new Runnable() {
public void run() {
try {
new Task(param1).run();
} catch(Exception e) {
// handle exception asynchronously
}
}
});
How about this:
A queue shared between all threads (make sure to be thread safe!),
Queue<Throwable> exceptionsToProcess;
Then, lock up your main method with a while loop:
//start threads, pass them the queue
while(true)
{
Throwable t;
while((t = exceptionsToProcess.poll()) == null);
//process t
}
The exceptions will be processed in the correct order, although your run the risk of a ConcurrentModificationException if you're not careful about thread safety.
Edit: This might be a useful queue class for this purpose: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/LinkedBlockingQueue.html

Categories