Alternate to Busy-Wait - java

In my application, Jobs will be submitted dynamically, I need to keep track of submitted job's completion. While I shutdown my application, I want to wait till all the submitted jobs completed. For this I maintain a list of submitted job ids. As soon as process completion notification is raised, I remove the id from the list. When shutdown is called, I am waiting till the list becomes empty.
while (!ids.isEmpty());
Is there a better way to this busy wait.

If you are implementing the job dispatching and running by hand by creating and starting threads, then you need to use Object.wait and Object.notify to implement a condition variable. It is a bit fiddly to get right ...
But a better approach is to use a ThreadPoolExecutor service for running your jobs. That allows you to submit all of the jobs, and then call shutdown and awaitTermination ... which will wait until all of the queued jobs have completed.

Are you reinventing an ExecutorService? In particular, its awaitTermination() method? And yes, awaitTermination() does not busy wait ...

You could try to do it the other way around:
Each job calls an "exit"-method (in the class that holds the ids) that checks if this is the last process to die. Then there will be no busy-wait loop. Provide each job with an "TerminationHandlerInterface" that have the exit-method.

Related

ExecutorService execute runnable in serial order

I'm using executor service with newSingleThreadExecutor to execute my Runnable task in serial order, however seems to be serial execution order is not guaranteed, as sometime tasks are executed in random order.
executorService = Executors.newSingleThreadExecutor();
executorService.submit(MyTask1);
executorService.submit(MyTask2);
MyTask performs some Asynchronous operation and send the result back to the class from where I'm executing the task.
though docs says, with newSingleThreadExecutor () tasks has to be executed serially,Im not able to find out what I'm missing here.any help would be appreciated.
Thanks
Since execution order is guaranteed to be sequential, you are problably not using a single thread executor in the code you are actually running.
As a work around, submit one task that does two things:
executorService.submit(() -> {MyTask1.run(); MyTask2.run();});
tl;dr
If the results you are watching arrive out-of-order are being produced asynchronously, then all is well. Async work is being done on its own separate timeline. By definition, the async work launched by task # 1 may not complete until long after tasks # 1, 2, & 3 are all done (for example).
Asynchronous means “don’t wait for me”
You mentioned:
MyTask performs some Asynchronous operation
Asynchronous execution means the calling code need not wait for the async operation to complete.
The calling code, your task submitted to the executor service, makes the request for async work to be done, and the task immediately continues. If that task has no further work, the task is complete. So the executor service can move on.
The executor service moves on. The executor service executes the second submitted task. Meanwhile, the async work requested above may not yet be done. Perhaps the async work is waiting on a resource such waiting for a call over the network to return, or the async work is waiting for a database query to execute. That, by definition of asynchronous, does not block the task submitted to the executor. The executor service is now running the 2nd submitted task, and may be a third or fourth, before, finally, your async work completes.
Feature, not a bug
In other words, a feature, not a bug. The ExecutorService returned by Executors.newSingleThreadExecutor() fulfilled its promise that “Tasks are guaranteed to execute sequentially”. The fact that as a by-product one of those tasks spins off async work does not change the fact that the tasks as submitted were indeed executed in their sequential order.

treating of asynchronous executor shutdown when waiting on future

I have an ssh client library implementation. Each connection has few executors. One is the thread pool using ScheduledThreadPoolExecutor, that is used to queue short lived tasks and timers. One is the read executor, used to hold a packet receiver task. One is the write executor, serially executing tasks, of which each sends one packet to the server. Of course both read and write executor are single threaded, and write executor is used as something like a message queue.
The problem that i have is: methods to queue a message, and some methods queuing tasks, return a CompletableFuture. I queue stuff with CompletableFuture.runAsync method. However, the connection may be asynchronously closed in an orderly or forced manner. In that case some or all pools are shutdown using the shutdownNow method.
What to do in the case that some threads, including threads outside of those pools, could wait for some task to complete synchronously, and there is a risk of asynchronous shutdownNow due to everything including network errors? shutdownNow does not issue future's cancel method. I do not care if actual tasks are interrupted or not, i just care that futures will block indefinitely if executor was shutdown while their task was still in the queue.
What is the best practice to handle this situation? What do people do/etc?
Okay, i believe I have an idea. it is the following:
Because parallel shutdown waits for all tasks to complete, and shutdownNow will just trash them without cancelling, and because I actually end up using completable futures all the time, I decided to maintain a set of completable futures of all kinds per connection, that would hold all tasks including message senders and normal tasks submitted to the task pool. Each method that closes the connection or begins orderly disconnect or so will go through the set and complete all futures exceptionally with some exception. That gives better errors than cancellation. Also nothing should happen if the task will cancel itself this way.
Instead of using runAsync, or normally creating a completable future in case of tasks not associated to runnables, I have a special method that creates such a task, adds it to the set, and attaches a function using CompletableFuture.whenCompleted(), that removes the task from the set if it completed for any reason. I also have runAsync that creates the task using the previously described method, and then submits a runnable using CompletableFuture.completeAsync.
That way all waiting threads should unblock on connection close and get a nice exception from all tasks including sent messages, no matter which method I would use to wait for completion, get() or join().

Maintaining a single executor service and shutting it down appropriately

My application requires that a certain job be done asynchronously, so I've resorted to the executor framework. This job (a Runnable) is expected to be run should a certain external interface be down (the vendor could be backed up for a while, say, 30 mins).
With this ask in mind, I believe I should maintain a single scheduled executor service with a fixed no. of core threads that perform these jobs when the interface I said above goes down for a brief moment (as a static variable in the class I need the thread pool in). I also don't think I should create an executor for every need to handle such a job (single scheduled thread pool executor), and shut down after a job is run, because that would defeat my purpose, wouldn't it? Because that could mean reserving a thread for every job during the backed up hour which sounds scary to me.
But, if I were to maintain such a single executor service, when would I be shutting down the executor? I understand that an executor once shut down can't be reused, while not shutting down the executor and keeping threads active could prevent the JVM from shutting down. How do I go about this?
My last statement was based on this from Effective Java 2nd edition:
And here is how to tell the executor to terminate gracefully (if you
fail to do this, it is likely that your VM will not exit):
executor.shutdown();
This job (a Runnable) is expected to be run should a certain external
interface be down (the vendor could be backed up for a while, say, 30
mins).
Above is your requirement. Now the solution entirely depends on how above situation is handled.
Trigger or event listener: If you have some trigger or event listener which can be called when it is found that a certain external interface is down, then in the that triggered code or event listener, you can create a ExecutorService, execute all your tasks (you can choose on fixed or pooled thread pool), and then on completion of all tasks, you can shutdown the ExecutorService
In this case, it is a good idea to create a ExecutorService, do tasks and shut it down. No need of long running ExecutorService.
Track or periodic check: If you have to track or check periodically whether certain external interface is down or not, then I think you can have a ScheduledThreadPoolExecutor implementation to have check after fixed time interval whether certain external interface is down or not, and if it is down then execute all your tasks. In this case you will NOT shutdown your ExecutorService and it will always be running.
Check scheduleAtFixedRate and scheduleWithFixedDelay for periodic task scheduling.
P.S.: Trigger and Track are my own convention I used tangentially as one word, so do infer it in technical words.
I understand that an executor once shut down can't be reused, while
not shutting down the executor and keeping threads active could
prevent the JVM from shutting down.
Yes, an executor once shut down can't be reused.
No, a running ExecutorService will not stop you JVM shutdown, but once JVM is shutdown that ExecutorService instance and its thread pool will be stopped and destroyed.

JAVA - Cancel the ThreadPoolExecutor running tasks

What I need is a method similar to shutdownNow, but, be able to submit new tasks after that. My ThreadPoolExecutor will be accepting a random number of tasks during my program execution.
You can grab the Future of each submission, store that Future in a collection, then when you want to cancel the tasks, invoke future.cancel() of all queued tasks.
With this solution the Exectuor is still running and any running tasks are cancelled or will not run if they are queued.
Why not create your own ExecutorService that exhibits this behaviour?
Is it not enough to just do getQueue() and clear it? If you really need to attempt to stop running tasks, you would need to subclass the ThreadPoolExecutor and essentially re-implement shutdownNow() but only copy the bit that sends an interrupt to each thread. Mind you this still isn't any guarantee that you will actually cause them to immediately cease and do no further calculation. You'll need a totally different approach if you need to do that.

In Java, how do I wait for all tasks, but halt on first error?

I have a series of concurrent tasks to run. If any one of them fails, I want to interrupt them all and await termination. But assuming none of them fail, I want to wait for all of them to finish.
ExecutorCompletionService seems like almost what I want here, but there doesn't appear to be a way to tell if all of my tasks are done, except by keeping a separate count of the number of tasks. (Note that both of the examples of in the Javadoc for ExecutorCompletionService keep track of the count "n" of the tasks, and use that to determine if the service is finished.)
Am I overlooking something, or do I really have to write this code myself?
Yes, you do need to keep track if you're using an ExecutorCompletionService. Typically, you would call get() on the futures to see if an error occurred. Without iterating over the tasks, how else could you tell that one failed?
If your series of tasks is of a known size, then you should use the second example in the javadoc.
However, if you don't know the number of tasks which you will submit to the CompletionService, then you have a sort of Producer-Consumer problem. One thread is producing tasks and placing them in the ECS, another would be consuming the task futures via take(). A shared Semaphore could be used, allowing the Producer to call release() and the Consumer to call acquire(). Completion semantics would depend on your application, but a volatile or atomic boolean on the producer to indicate that it is done would suffice.
I suggest a Semaphore over wait/notify with poll() because there is a non-deterministic delay between the time a task is produced and the time that task's future is available for consumption. Therefore the consumer and producer needs to be just slightly smarter.

Categories

Resources