Knowing when all threads complete and dealing with exceptions - java

I am using the Executor framework to kick off several threads using a threadpool i.e newFixedThreadPool. I use threadpool.submit(aThread) to submit jobs to be executed by the threadpool and this works fine however I need to determine when all the threads are complete so that I can continue with other processing. I looked at using Future.get() which blocks until the thread is complete the problem here being that it blocks until a result is available. I also looked at using continuously calling the isTerminated() method followed by a sleep after issuing the shutdown to check if all threads are complete but this doesn't seem neat to me. Is there another cleaner way to this? Also if there is an exception raised in any one of the threads I want to be able to terminate all other running threads and also stop any queued up thread in the pool from starting. What is the best mechanism to do this?
Look forward to hearing your replies
TIA

Use ExecutorService#shutdown() and then ExecutorService#awaitTermination()
For example:
ExecutorService service = Executors.newCachedThreadPool();
service.submit(...);
service.submit(...);
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
// All tasks have now finished
As far as notifying you when a task fails with an exception. You'll have to provide a ThreadFactory to the ExecutorService that sets an "uncaught Exception handler" for each thread it creates. This Exception handler can then terminate the running tasks.

One of the cleaner ways to approach this is by modifying the tasks that are submitted. By registering a callback with each task, it can notify of normal completion or an exception without any polling by the main thread.
You can write a simple wrapper that will do this for any Runnable.
Or, following that example, you can extend the idea to wrap any Callable.
class CallbackTask<T>
implements Callable<T>
{
private final Callable<? extends T> task;
private final Callback<T> callback;
CallbackTask(Callable<? extends T> task, Callback<T> callback)
{
this.task = task;
this.callback = callback;
}
public T call()
throws Exception
{
try {
T result = task.call();
callback.complete(result);
return result;
}
catch (Exception ex) {
callback.failed(ex);
throw ex;
}
}
}

Related

Java Rest API Calling another Rest without waiting for the response - in JAX-RS

I have a case to be implemented in my project.Below is a sample rest service which has to be implemented
#GET
#Path("/test/{id}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public String getData(#PathParam("id") String id) {
//Some processing to get value of String
String result = doSomeProcessing();
//I want to return this result to GUI and call one more rest api
// and end this process without waiting for response from second
//call
new Thread(){
//call second rest api
}.start();
return result;
}
Is this good approach using new Thread to call second rest API and return result without waiting for response from second rest API ?
I have also looked into Asynchronous Rest call, but it doesn't exactly suit my requirement. Please advice. Thanks in Advance
Avoid starting Threads directly. Consider an ExecutorService instead as shown below:
#Singleton
#Path("foo")
public class FooResource {
private ExecutorService executor;
#PostConstruct
public void onCreate() {
// Creates a thread pool that reuses a fixed number
// of threads operating off a shared unbounded queue
this.executor = Executors.newFixedThreadPool​(10);
}
#GET
public Response getFoo() {
String result = doSomeProcessing();
// Submits a Runnable task for execution
executor.submit(new LongRunningTask());
return Response.ok(result).build();
}
#PreDestroy
public void onDestroy() {
// Initiates an orderly shutdown in which previously submitted
// tasks are executed, but no new tasks will be accepted.
this.executor.shutdownNow();
}
}
public class LongRunningTask implements Runnable {
#Override
public void run() {
try {
// Simulate a long running task
// Don't do it in a real application
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Explore the Executors API for details on how to create an ExecutorService instance.
In Java SE and in a Servlet container, you can use an ExecutorService for your long running task. In a Java EE container, you should use a ManagedExecutorService instead:
#Resource
ManagedExecutorService executor;
Once it's a resource managed by the container, you don't need to instantiate and dispose it manually.
I not sure what do you exactly mean by "calling the second REST API" so I assume that you're sending an HTTP request to another external API, i.e "second REST API".
You can use Apache HC to send the request and skip waiting for the response. See its fluent API which is easy to use. Async.execute is the one that ought to be used in your case. The Async class uses a thread-pool underneath to handle background requests.
I should mention that I haven't used any other HTTP client libraries. There might be other choices out there with almost the same functionality.
Side Note I strongly suggest ExecutorService, esp. ThreadPoolExecutor instead of creating new threads. It has more control over life-cycle of threads and manages system resource efficiently. ExecutorService has methods for fire and forget scenarios (submit). However, this only makes sense when your "second REST API" call is actually implemented in another method in your application and lives within the same JRE.
I'd say yes and no; there is nothing "wrong" about calling another service asynchronously (ex: a metrics subsystem to register that a call to that service was made). However, I wouldn't create threads straight in the getData method, I would use another (injected) object to hide the implementation detail (ex: just calling some sort of myOtherService.submit(something). That way you can easily switch from something synchronous, to asnychronous and even change the async method to your liking.
As to the actual implementation, instead of creating threads, I would submit callables to an executor service instead so you save the overhead of creating actual system threads, or you could even have one or more threads waiting on a blocking queue and just put jobs in that queue for threads to pick them up.

stop Spring Scheduled execution if it hangs after some fixed time

I have used Spring Framework's Scheduled to schedule my job to run at every 5 mins using cron. But sometime my job waits infinitely for an external resource and I can't put timeout there. I can't use fixedDelay as previous process sometime goes in wait infinitely mode and I have to refresh data at every 5 mins.
So I was looking any option in Spring Framework's Scheduled to stop that process/thread after a fixed-time either it run successfully or not.
I have found below setting which initialized ThreadPoolExecutor with 120 seconds for keepAliveTime which I put in #Configuration class. Can anybody tell me will this work as I expected.
#Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
int coreThreads = 8;
int maxThreads = 20;
final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
coreThreads, maxThreads, 120L,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()
);
threadPoolExecutor.allowCoreThreadTimeOut(true);
return threadPoolExecutor;
}
I'm not sure this will work as expected. Indeed the keepAlive is for IDLE thread and I don't know if your thread waiting for resources is in IDLE. Furthermore it's only when the number of threads is greater than the core so you can't really know when it happen unless you monitor the threadpool.
keepAliveTime - when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
What you can do is the following:
public class MyTask {
private final long timeout;
public MyTask(long timeout) {
this.timeout = timeout;
}
#Scheduled(cron = "")
public void cronTask() {
Future<Object> result = doSomething();
result.get(timeout, TimeUnit.MILLISECONDS);
}
#Async
Future<Object> doSomething() {
//what i should do
//get ressources etc...
}
}
Don't forget to add #EnableAsync
It's also possible to do the same without #Async by implementing a Callable.
Edit: Keep in mind that it will wait until timeout but the thread running the task won't be interrupted. You will need to call Future.cancel when TimeoutException occurs. And in the task check for isInterrupted() to stop the processing. If you are calling an api be sure that isInterrupted() is checked.
allowCoreThreadTimeOut and timeout setting doesn't help cause it just allow work thread to be ended after some time without work (See javadocs)
You say your job waits infinitely for an external resource. I'am sure it's because you (or some third-party library you using) use sockets with time out infinite-by-default.
Also keep in mind what jvm ignores Thread.interrupt() when it blocked on socket.connect/read.
So find out witch socket library used in your task (and how exactly it used) and change it's default timeout settings.
As example: there is RestTemplate widely used inside Spring (in rest client, in spring social, in spring security OAuth and so on). And there is ClientHttpRequestFactory implementation to create RestTemplate instances. By default, spring use SimpleClientHttpRequestFactory which use JDK sockets. And by default all it's timeouts are infinite.
So find out where exactly you freeze, read it's docs and configure it properly.
P.S. If you don't have enough time and "feeling lucky" try to run your app with setting jvm properties sun.net.client.defaultConnectTimeout and
sun.net.client.defaultReadTimeout to some reasonable values (See docs for more details)
The keepAliveTime is just for cleaning out worker threads that hasn't been needed for a while - it doesn't have any impact on the execution time of the tasks submitted to the executor.
If whatever is taking time respects interrupts you can start a new thread and join it with a timeout, interrupting it if it doesn't complete in time.
public class SomeService {
#Scheduled(fixedRate = 5 * 60 * 1000)
public void doSomething() throws InterruptedException {
Thread taskThread = new TaskThread();
taskThread.start();
taskThread.join(120 * 000);
if(taskThread.isAlive()) {
// We timed out
taskThread.interrupt();
}
}
private class TaskThread extends Thread {
public void run() {
// Do the actual work here
}
}
}

Is there a way to terminate CXF web service call?

I am using CXF to call web service. It is used in a simple way like it is described in the documentation:
HelloService service = new HelloService();
Hello client = service.getHelloHttpPort();
String result = client.sayHi("Joe");
How can I terminate this service call when it takes time?
I found only one related question but this doesn't provide any solution.
How to terminate CXF webservice call within Callable upon Future cancellation
I think this is more of a function of the web server. For example, if you use Jetty to serve your CXF content, then you can set the thread pool to something that'll watch your threads.
ThreadPoolExecutor pool = new ThreadPoolExecutor(...);
ExecutorService svc = new ControlledExecutorService(pool);
server.setThreadPool(new org.eclipse.jetty.util.thread.ExecutorThreadPool(svc));
Then for the custom executor service (sorry, all code typed in the browser directly. I'm on an iPad with no Java. So you'll likely need to make slight adjustments, but the useful parts should be here):
public class ControlledExecutorService implements ExecutorService {
private ExecutorService es;
public ControlledExecutorService(ExecutorService wrapped) {
es = wrapped;
}
#Override
public void execute(final Runnable command) {
Future<Boolean> future = submit(new Callable< Boolean >() {
public Boolean call() throws Exception {
command.run();
return true;
}
});
// Do the proper monitoring of your Future and interrupt it
// using Future.cancel(true) if you need to.
}
}
Be sure to pass true to cancel() so that it sends the interrupt.
Also remember than just like with any thread, just because you send it an interrupt, it doesn't mean it'll comply. You have to do some work in your threads to make sure they're well behaved. Notably, periodically check Thread.currentThread().isInterrupted() and properly handling InterruptedException to pick it up and stop the task gracefully instead of just letting the exception blow everything up.

Phaser instances & Spring MVC

I have a spring #Controller that has a request mapping.
When requests are sent to it it creates a deferred result and runs a method on a delegator class.
In the controller:
#ResponseBody
#RequestMapping(MenuModelCodes.MENU_NAME)
DeferredResult<HttpEntity<?>> getModelCodesWithClass(String target) {
final DeferredResult<HttpEntity<?>> deferredResult = getNewDeferredResult();
delegator.doStuff(target);
return deferredResult;
}
The doStuff method in the delegator is #Async annotated - so it's running in another thread.
In this thread a new Phaser is created to keep track of child threads it will create.
The delegator thread itself registers with the phaser, and triggers a call to a method in "AnotherClass" that is also #Async annotated. I.e. the delegator is now spawning children.
The delegator:
public class Delegator {
#Async
public Object doStuff(String requestURI) {
Phaser phaser = new Phaser();
phaser.register();
Object result = anotherClass.createThreadDoWork(phaser);
phaser.arriveAndDeregister();
//Wait until phaser is completed
while (!phaser.isTerminated()) {}
return result;
}
}
Each child spawned thread created by a call in the delegator to createThreadDoWork here registers itself with the phaser, does some work and then arrives and deregisters.
AnotherClass:
public class AnotherClass {
#Async
public void createThreadDoWork(Phaser phaser) throws Throwable {
phaser.register();
//some kind of logic / rest call etc.
phaser.arriveAndDeregister();
}
}
When all child threads complete, the delegator which is sitting at this piece of code:
while (!phaser.isTerminated()) {}
Will continue, set its deferred result and the delegator thread will end.
So here's the question(s):
I want a Phaser for every request - i.e. I create a new Phaser() everytime a request creates a new delegator thread.
If I receive 5 requests to my controller, they each spawn a delegator thread, each delegator creates a new Phaser and passes it to their children.
However, as soon as one of the threads completes its processing and its specific instance of the Phaser is terminated, the other delegator threads continue and return without having done their tasks.
Can Phasers be used like this? Am I doing something wrong? I thought this would be a useful way to track the completion of child threads and wait for them to complete?
Thanks.
Can Phasers be used like this?
Yes, it can be used like this, and usually would be as a synchronization barrier.
Am I doing something wrong?
Yes. Do not do
while (!phaser.isTerminated()) {}
The busy spinning will kill you. Instead do:
phaser.awaitAdvance();
This would force you to register a little differently. You would have to register a thread before you actually start running.
Also if you are in advancing the phaser where you have a multiple phases then you would have to re-evaluate using a phaser.
I thought this would be a useful way to track the completion of child
threads and wait for them to complete?
If you do have a number of unknown threads being created it would be useful to use a Phaser.

In Java how to shutdown executorservice when it may submit additional tasks to itself

I have a pipeline of tasks (each task in the pipeline has different parallelism requirements), each task works in a different ExecutorService. Tasks work on packets of data, so if we have 10 datapackets then 10 tasks will be submitted to service1, one task per data packet. Once a task submitted to service1 has actually invoked it may submit a new task to work further on the datapacket to service2, service3 or not.
The following code works fine, i.e.:
shutdown() is invoked on service1 after everything has been submitted to service1
Then awaitTermination() does not return until all the tasks that were submitted before the shutdown() have actually completed running.
-- shutdown() is then invoked on service2 but because all tasks submitted to service1 have completed, and all tasks are submitted to service2 from tasks on service1 all tasks have been submitted to service2 before shutdown() is called on service2.
-- and so on for service3
ExecutorService[] services = {
service1,
service2,
service3};
int count = 0;
for(ExecutorService service: services)
{
service.shutdown();
service.awaitTermination(1, TimeUnit.HOURS);
}
However I have now added a case whereby service2 can break a datapacket into a smaller packet and submit additional tasks on service2 and the code is now failing. The problem is that shutdown() is called on service2 once all the tasks on service1 have completed, but now we want to submit additional service2 tasks from a task running in service2
My questions:
Does shutdown() rerun after all submitted tasks have finished running, or does it return immediately but just doesn't stop already submitted tasks from running ? Update:answered below
How do I solve my new problem ?
"shutdown" simply tells the pool not to accept any more work. It does nothing more. All existing submitted work will be executed as normal. When the queue is drained, the pool will actually destroy all it's threads and terminate.
The problem here is that you're saying that tasks in service2 will submit additional tasks to service2 for processing. There seems to be no way to know when you should actually call a shutdown. But alas, there is an alternative, assuming these smaller packets don't break down further into service.
List<Future<Void>> service2Futures = new ArrayList<Future<Void>>();
service2Futures.add(service2.submit(new Callable<Void>() {
public Void call() throws Exception {
// do your work, submit more stuff to service2
// if you submit Callables, you could use Future.get() to wait on those
// results.
return null;
}
}));
for (Future<Void> future : service2Futures) {
future.get();
}
service2.shutdown();
...
What's going on here is that you're storing Future objects for the top level submitted tasks (you'll have to use Callable and not Runnable). Instead of immediately shutting the pool down after submission, you simply collect up the Future objects. You then wait until they are all done running by cycling through them, and calling get() on each one. The "get()" method blocks until the thread running that task has completed.
At that point, all of the top level tasks are complete, and they will have submitted second level tasks. You can now issue a shutdown. This assumes the second level tasks don't submit more stuff to service2.
This all being said, if you're using java 7, you should consider taking a look at ForkJoinPool and RecursiveTask instead. It probably makes more sense for what you're doing.
ForkJoinPool forkJoinPool = new ForkJoinPool();
RecursiveAction action = new RecursiveAction() {
protected void compute() {
// break down here and build actions
RecursiveAction smallerActions[] = ...;
invokeAll(smallerActions);
}
};
Future<Void> future = forkJoinPool.submit(action);
ExecutorService#shutdown lets already submitted tasks finish whatever they are doing - javadoc extract:
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.
In practice, you can consider that a call to shutdown does several things:
the ExecutorService can't accept new jobs any more
existing threads are terminated once they have finished running
So to answer your questions:
if you have submitted all your tasks to service1 before you call service1.shutdown (if you submit anything after that call you will get an exception anyway), you are fine (i.e. if those tasks submit something to service2 and service2 is not shutdown, they will be executed).
shutdown returns immediately and does not guarantee that already submitted tasks will stop (they could run forever).
The problem you are having is probably linked to how you submit your tasks from one service to another and it seems difficult to solve it with only the information you have given.
The best way would be to include a SSCCE in your question that replicates the behaviour you are seeing.
Instead of shutting down the ExecutorService, you should track the tasks themselves. they can pass around a "job state" object in which they use to keep track of outstanding work, e.g.:
public class JobState {
private int _runningJobs;
public synchronized void start() {
++_runningJobs;
}
public synchronized void finish() {
--_runningJobs;
if(_runningJobs == 0) { notifyAll(); }
}
public synchronized void awaitTermination() {
while(_runningJobs > 0) { wait() }
}
}
public class SomeJob implements Runnable {
private final JobState _jobState;
public void run() {
try {
// ... do work here, possibly submitting new jobs, and pass along _jobState
} finally {
_jobState.finish();
}
}
}
// utility method to start a new job
public static void submitJob(ExecutorService executor, Runnable runnable, JobState jobState) {
// call start _before_ submitting
jobState.start();
executor.submit(runnable);
}
// start main work
JobState state = new JobState();
Runnable firstJob = new SomeJob(state);
submitJob(executor, firstJob, state);
state.awaitTermination();
When you call shutdown it does not wait all task will be finished. Do it as you do with awaitTermination.
But once shutdown was called - new task are blocked. Your executor service reject all new task. For ThreadPoolExecutor rejected task handle in RejectedExecutionHandler. If you specify you custom handler you can process rejected after shutdown task. This is one of workarounds.
Matts question looks like it may well work but Im concerned it may cause new issues.
Ive come up with a solution which works without many code changes for my scenario, although it seems a bit clunky
Ive introduced a new service (service2a) that runs the same task as service2. When a task in service2 wants to submit a small data packet it submits it to service2a rather than service2 so all sub packets are submitted to service2a before service 2 shutdowns. This works for me as the smaller data packets dont need to be broken down into further subpackets and the subpackets idea only applies to service2(a) not any of the other services.

Categories