Get Runnable objects I scheduled using ScheduledThreadPoolExecutor when using shutdownNow() method - java

I'm using ScheduledThreadPoolExecutor.schedule(Runnable,int,TimeUnit) to schedule some objects of a class that implements Runnable.
At some point in time, my application is then shutting down, and I use ScheduledThreadPoolExecutor.shutdownNow(). According to the documentation it returns a list of ScheduledFuture's.
What I really want to do is get a hold of the object that I originally scheduled, and get a bit of data from it which I will then output saying that it was unable to execute. This would then, later, be used by the application to attempt to execute it when the application then starts back up.

The usual way to get info about objects submitted to an executor is to maintain a pointer to the original objects (be they extensions to Callable, Runnable, etc). After you call shutdownNow(), and take into account the Runnable's returned by that which were awaiting execution, you can use that to prune your original list of objects and just interrogate the ones that were actually run.

If you just want to present the information to the user, the simplest approach might be to implement a meaningful toString() method for the Runnables you'r scheduling. Then you can simply iterate the list the Executor gives you and log what you get.
But the sad truth is that your original objects get wrapped by the Executor, though. Then you would need to keep a list of what you pass to the Executor manually and let the Runnables remove themselves from this list when they get executed. Obviously, you would need to use a thread-safe list for this purpose.

Related

When to use CompletableFuture#thenApply(..) over thenApplyAsync(..)?

In context of CompletableFuture I understand that thenApply(..) may use the current thread and may use the a pre-defined executor (e.g. ForkJoinPool) while thenApplyAsync(..) ensures that the pre-defined executor will be always used.
Far as I see the thenApplyAsync(..) seems be more "reliable" as it never blocks the current thread while thenApply(..) might be a surprise.
My question: Which example/scenario would be valid to use thenApply(..) rather than thenApplyAsync(..)?
Thanks, Christoph
Yes, thenApplyAsync would use some excecutor. This means that some Runnable object must be created and put in the executor's queue. If the function you want to execute after the complethion of this CompletableFuture is very simple, then invoking this method directly may be more efficient than creating envelope Runnable.

thread pool - make a new one per task, detect when a set of tasks is done

Running concurrent tasks via ThreadPoolExecutors. Since I have 2-3 sets of tasks to do, for now have a map of ThreadPoolExecutors and can send a set of tasks to one of them.
Now want to know when a pool has completed all tasks assigned to it. The way its organized is that I know before hand the list of tasks, so send them to a newly constructed pool, then plan to start pooling/ tracking to know when all are done.
One way would be to have another pool with 1-2 threads, that polls the other pools to know when their queues are empty. If a few scans show them as empty (with a second sleep between polling, assumes they are done).
Another way would be to sub class ThreadPoolExecutor , keep a track via the queue and over ridding afterExecute(Runnable r, Throwable t) so can know exactly when each task is done, good to show status and know when all are complete if everything moving smoothly.
Is there an implementation of the second some where? Would be good to have an interface that listeners can implement, then add them selves to the sub classed method.
Also looking for an implementation :
To to ask a pool to shut down within a time out,
If after a time out the shut down is not complete then call shutdownNow()
And if this fails then get the thread factory and stop all threads in its group. (assumes that we set the factory and it uses a group or other way to get a reference to all its threads)
Basically as sure a way as we can, to clean up a pool so that we can have this running in an app container. Some of the tasks call selenium etc so there can be hung threads.
The last ditch would be to restart the container (tomcat/jboss) but want that to be the last ditch.
Question is - know of an open source implementation of this or any code to start off with?
For your first question, you can use a ExecutorCompletionService. It will add all completed tasks into a Queue so with a blocking queue you can wait until all tasks arrived at the queue.
Or create a subclass of FutureTask and override its done method to define the “after execute” action. Then submit instances of this class wrapping your jobs to the executor.
The second question has a straightforward solution. “shut down within a time out, and if after a time out the shut down is not complete then call shutdownNow()”:
executor.shutDown();
if(!executor.awaitTermination(timeout, timeUnit))
executor.shutdownNow();
Stopping threads is something you shouldn’t do (Thread.stop is deprecated for a good reason). But you may invoke cancel(true) on your jobs. That could accelerate the termination if your tasks support interruption.
By the way it looks very unnatural to me having multiple ThreadPoolExecutors and playing around with shutting them down instead of simply having one ThreadPoolExecutor for all jobs and letting that ThreadPoolExecutor manage the live cycle of all threads. That’s what the ThreadPoolExecutor is made for.

Can I retrieve the task running in a ScheduledExecutorService without keeping its reference?

I am currently modifying an application to use a ScheduledExecutorService in place of a Timer and I used to access the scheduled task with a Map I kept, and it allowed me to cancel() the task as well as accessing it.
With this API it seems that I have to maintain two Maps, one for accessing the tasks and one for the SheduledFuture<?>s returned by schedule() to be able to cancel them.
I read this post but it looks very heavy to implement compared to what I did with a Timer (Only one Map was needed).
This is a simple application that has two tasks that need to be accessed and cancelled.
Is there something I didn't get or are `Executor's not what I need for something this simple?
So you want following:
You want the instance of task submitted as it has some info.
You need ability to cancel the submitted task.
Modify Class definition of your submitted task to have an instance of Future in it. Now when you submit your task to ExecutorService it will return a Future , you can set this Future object in your submitted task object. So now you just need to retain the submitted task and you will info as well as ability to cancel task via future.

ExecutorService-like class where user controls when Callables are called

I was using an ExecutorService to schedule tasks to be executed in future. After seeing some "odd" behavior where my Callable was getting executed before I called get() on the Future object returned by submitting my Callable to the ExecutorService pool, I read some documentation and found that the submitted task will get executed between the time it gets submitted or at the latest when get() is called on the Future object.
My question - is there any class that would allow Callables to be submitted to it and ONLY executed when get() is called on it? At this point, it seems like just managing the Callables myself and calling call() on them myself when I am ready for them to be executed seems like it'd accomplish what I want, but I wanted to make sure there was no service already implemented that accomplished this.
In short, is there any alternative to ExecutorService that lets me control when Callables submitted to it are called? Note - the time in the future that I want them called is variable and not determined as I may decide not to call them so a ScheduledExecutorService pool won't work here.
Thanks much!
Sounds like you really want to use a Queue<Callable> instead and just poll the queue for tasks.
That way you can submit as many tasks as you like and execute them at your will - one by one.

Java Threads calling methods on common Data Collector Object possible?

The idea: I have a JAX-RS webservice servlet (Object called webServlet) which instantiates a data collecting Object dataCollector and passes this object on to multiple threads in their constructor. These threads query websites for results and then call the dataCollector.add(result) method to add the results to a Queue within the shared dataCollector.
I have two questions regarding this idea:
1) Can multiple threads call methods of a single shared object at the same time?
2) How does my webServlet object check when all threads are terminated to render a result page? Do I have to let my webServlet wait while all threads are running so I have a complete result list and how would I do that?
1) Yes, but perhaps not safely. In particular, if the queue in your dataCollector isn't a thread-safe queue like a ConcurrentLinkedQueue, you run the risk of a ConcurrentModificationException when a thread calls add() on it.
2) a) Use an ExecutorService (perhaps obtained from Executors) to submit Callables or Runnables. Keep the Futures that are returned and use get() to wait until he work is done.
b) You don't have to. The choice is up to you. If you send the response before the work is done, you obviously won't have a complete result yet.
c) See a).
If this is all new to you, you may want to check out Concurrency in the Java Tutorials.

Categories