I have written some code that submits a callable to an executor, storing the future in a map against an id. In the call method I wait for a flag to be set before proceeding. Basically I need to wait for an external operation to return to me and say we are done - here is the data and now you can continue... I dont think what I have is correct:
public class MyClass implements Callable<Boolean> {
---
---
private boolean done = false;
#override
public Boolean call() {
-- wait for flag to be set...
//continue....
}
}
--main code--
//create the above class..
//submit it...
//get the future store in map...
//-- wait for response from external application...
///tie it up with an id
//set the attribute so the callable can continue and complete..
Questions:
The above will not work as I am returned a Future and not the object. I was thinking of maybe creating a new interface which inherits from the callable class - does that make sense?
I need the thread to wait and then die if no response is received. Is it possible to set that on a thread at all?
You can schedule a task which will cancel the waiting task. When the waiting task finishes it can cancel the scheduled task. (which ever finished first will cancel the other)
This assumes you have a task which is interruptible in the first place.
there is a wait(long timeout) function available.. heres some documentation on it
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html
with this wait(long timeout) function, the thread will wait until it gets a notify() (or notifyAll()) OR until the timout expires.
any of the following will break the wait();
notify();
notifyAll();
timout gets reached
Use the Future#get(long, TimeUnit).
This will wait for some time for an answer, and throw a TimeoutException if there is no return value in the given period. Then just catch the exception and let the thread finish grafefully.
Related
I have a method producer.postMessage(message) which sends a message to some queue. If for some reason the message could not be sent in a period of time I want this task to be canceled. I came up with the implementation below. My question is if there is an interrupt can I be sure the Future task/ executor service are all shutdown and if not what changes need to be made to make this working without any threads not being terminated.
Thanks a lot
public void postMessage(final Object object)
{
LOG.debug("postMessage object " + object.getClass().getSimpleName());
Message message = new Message("task", 10, object);
try
{
ExecutorService ex = Executors.newSingleThreadExecutor();
Future<?> f = ex.submit(new Runnable()
{
public void run()
{
producer.postMessage(message);
LOG.debug("Finished sending message for " + object.getClass().getSimpleName());
}
});
f.get(5, TimeUnit.SECONDS);
ex.shutdown();
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
LOG.error("Could not deliver message to the queue, Check AMQ is running");
}
}
The shutdown() method on an Executor will stop it from accepting new tasks, but attempts to complete the running tasks. You should use method shutdownNow() to have the Executor request that currently running tasks are stopped.
This may not be necessary however, if you use method cancel(boolean mayInterruptIfRunning) on the Future object. f.get(5, TimeUnit.SECONDS) will wait at most 5 seconds for completion of the tasks before returning. Since you submit a Runnable rather than a Callable, the return will always be null; Runnables can't return a result, while Callables can. What you can do is call isDone() on the Future after the get with a 5 second timeout, and if it returns false, it means the tasks has not completed. In that case you can then call cancel(true) on the Future to attempt to cancel the task. The true argument indicates that you'll allow the Future to interrupt the thread if it is running. You may want to catch InterruptedExceptions in your Runnable and log them. Note however that not every call may respond to interrupt requests (for example, some I/O operations may not, while a lot of Java NIO stuff does).
Calling the shutdown on the executor may no longer be necessary, since it's only used for a single task and should have no other waiting or running tasks, but it's probably still good form.
So your code would become:
f.get(5, TimeUnit.SECONDS);
if (!f.isDone())
f.cancel(true);
ex.shutdown();
I am trying to use a Third Party Internal Library which is processing a given request. Unfortunately it is synchronous in nature. Also I have no control on the code for the same. Basically it is a function call. This function seems to a bit erratic in behavior. Sometimes this function takes 10 ms to complete processing and sometimes it takes up to 300 secs to process the request.
Can you suggest me a way to write a wrapper around this function so that it would throw an interrupted exception if the function does not complete processing with x ms/secs. I can live with not having the results and continue processing, but cannot tolerate a 3 min delay.
PS: This function internally sends an update to another system using JMS and waits for that system to respond and sends apart from some other calculations.
Can you suggest me a way to write a wrapper around this function so that it would throw an interrupted exception if the function does not complete processing with x ms/secs.
This is not possible. InterruptException only gets thrown by specific methods. You can certainly call thread.stop() but this is deprecated and not recommended for a number of reasons.
A better alternative would be for your code to wait for the response for a certain amount of time and just abandon the call if doesn't work. For example, you could submit a Callable to a thread pool that actually makes the call to the "Third Party Internal Library". Then your main code would do a future.get(...) with a specific timeout.
// allows 5 JMS calls concurrently, change as necessary or used newCachedThreadPool()
ExecutorService threadPool = Executors.newFixedThreadPool(5);
...
// submit the call to be made in the background by thread-pool
Future<Response> future = threadPool.submit(new Callable<Response>() {
public Response call() {
// this damn call can take 3 to 3000ms to complete dammit
return thirdPartyInternalLibrary.makeJmsRequest();
}
});
// wait for some max amount of time
Response response = null;
try {
response = future.get(TimeUnit.MILLISECONDS, 100);
} catch (TimeoutException te) {
// log that it timed out and continue or throw an exception
}
The problem with this method is that you might spawn a whole bunch of threads waiting for the library to respond to the remote JMS query that you would not have a lot of control over.
No easy solution.
This will throw a TimeoutException if the lambda doesn't finish in the time allotted:
CompletableFuture.supplyAsync(() -> yourCall()).get(1, TimeUnit.SECONDS)
Being that this is 3rd party you cannot modify the code. As such you will need to do two things
Launch the execution in a new thread.
Wait for execution in current thread, with timeout.
One possible way would be to use a Semaphore.
final Semaphore semaphore = new Semaphore(0);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// do work
semaphore.release();
}
});
t.start();
try {
semaphore.tryAcquire(1, TimeUnit.SECONDS); // Whatever your timeout is
} catch (InterruptedException e) {
// handle cleanup
}
The above method is gross, I would suggest instead updateing your desing to use a dedicated worker queue or RxJava with a timeout if possible.
I have a servlet, and it is a singleton.
In the init, I create the producer and the consumers.
consumer = new MyThread();
consumer.start();
and the method run is like this:
#Override
public void run() {
while (!isShutdown()) {
if (queue.isEmpty())
queue.wait();
else
...
}
}
then i have the destroy method.
that set shutdown to true and I use .join
consumer.setShutdown(true);
consumer.join();
but the method .join got lock.. and never finishes.
If I change the queue.wait to Thread.sleep(), it works... but I don't want to change... what I'm doing wrong?
if I don't finish the thread, I got it:
SEVERE: The web application [/test] appears to have started a thread named [Comsumer0] but has failed to stop it. This is very likely to create a memory leak.
Using wait/notify methods is the old way to create a Consumer-Producer pattern.
It is better to use BlockingQueue.
BlockingQueue.put() - for Producer, and BlockingQueue.poll() - for Consumer.
BlockingQueue hides wait method underneath BlockingQueue.poll, BlockingQueue.put and will block a Consumer thread until Producer adds value to queue.
To fix the example above, you should make it wait for a finite amount of time like queue.wait(1000), or wake consumer thread explicitly calling queue.notify().
Most likely the queue is empty and since you have shutdown you never send anything into the queue to cause it to wake up.
Fix this either by sending a dummy message to the queue after setting the shutdown flag or by just removing the shutdown flag completely and sending a shutdown command to the queue.
Also be aware that if your shutdown flag is not volatile (or AtomicBoolean) then one thread may not see it being set by the other due to caching inside the CPU.
This is what the BlockingQueue is for:
BlockingQueue queue = new ArrayBlockingQueue(5);
// ...
while (!isShutdown()) {
Object poll = queue.poll(5, TimeUnit.SECONDS);
}
you should change the design as advised above, or if you don't want to change your code, change your setShutdown() method body and statement to notify the queue.
public void setShutdown(boolean shutdown) {
this.shutdown = shutdown;
this.queue.notifyAll();
}
So I have this in a method:
Runnable task = new PostLoadRunnable(tool, archive);
SwingUtilities.invokeLater(task);
But I want to make it so that the current method does not continue until the task thread has completed. I want to do something like join() but I can't work out how to do it. task.join() and Thread.task.join() doesn't work and Thread.currentThread().join() doesn't give me any options to join it to the thread that I want.
How do I stop the method until task is finished?
You can accomplish this using a CountDownLatch. In your PostLoadRunnable run method you can have the following code in the finally section.
public void run() {
try {
...
} finally {
latch.countDown();
}
}
CountDownLatch latch = CountDownLatch(1);
Runnable task = new PostLoadRunnable(tool, archive, latch);
SwingUtilities.invokeLater(task);
latch.await();
You don't want to do this at all. You state in comments that this code runs in the event dispatcher thread. You must not block this thread. Otherwise you will freeze the entire UI and the user will be most unhappy.
What you probably should do is disable the relevant parts of the UI until the task has completed. But without knowing your actual wider requirement it isn't possible to be sure.
I have a Runnable implementation that does some work which might take some time and I am trying to schedule it using ScheduledThreadPoolExecutorwith scheduleAtFixedRate method. Now I want to ensure that shut down is graceful that means, Before terminating, task should be allowed to run completely. I have written following code for shutdown.
public void shutDown() throws Exception {
try {
LOG.info("Gracefully shutting down executor");
executor.shutdown();
if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) {
// cancels currently executing tasks.
LOG.info("Executor is still alive. Forcing executor thread pool to shut down");
executor.shutdownNow();
// Wait a while for tasks to respond to being cancelled
if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) {
LOG.fatal("Executor thread pool did not terminate");
throw new Exception("Unable to shut down executor thread pool forcefully");
}
LOG.info("Executor shut down.");
}
} catch (Exception e) {
LOG.error("Exception shutting down executor", e);
throw e;
}
}
But problem with this is, I have to specify time to wait explicitly and I can not predict time taken by task in advance. Is there a way to make executor wait indefinitely until executing task finishes without having to mention time to wait? Or is there a better way to work on above scenario?
Thanks
Jitendra
Simplest solution is to "overprovision" so to speak. I suggest you use a huge timeout period that in no way can be exceeded by the time needed for a single task to execute, like:
// do you have tasks that can take more than 2^63 - 1 days to finish? :)
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
Use shutdown() to begin a graceful termination, and then use awaitTermination(long, TimeUnit) to wait for the executor service to finish shutting down.
As it was noted in the comment executor.shutdown() is not forcing any tasks to exit but rather it prevents new ones from being accepted. Have a look in the javadoc.
Another advice is if you want to get hold of your tasks as soon as they complete, you can implement Callable<T> instead of a Runnable that it's of a generic type and returns a value of type T. Then you can wrap this Callable<T> into a FutureTask<V> and submit that to your ScheduledThreadPoolExecutor. You can then loop through your tasks as soon as they have completed their work and are available. So in short something like this (notice as soon as we are done loading the scheduler with tasks it's safe to shut it down meaning that we don't allow any further tasks to be submitted from then on):
ScheduledExecutorService schedulerExecutor = Executors.newScheduledThreadPool(n);
Callable<Integer> myTask = . . .;
FutureTask<Integer> task = new FutureTask<Integer>(myTask);
schedulerExecutor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
schedulerExecutor.shutdown();