How can I interrupt method execution by time? - java

Suppose method A is calling method B. Can method A control execution time of method B and interrupt it in, suppose, 60 seconds (method B can hangs for example)?

You can run tasks asynchronously using an ExecutorService, obtaining a Future that enables you to get the result of the task when it is done. There's a get method on the Future that you can call to wait for the answer, with a timeout. If it times out, you try to cancel the task by calling cancel on the Future.
ExecutorService executorService = Executors.newSingleThreadExecutor();
// Callable that has a run() method that executes the task
Callable<String> callable = ...;
// Submit the task for execution
Future<String> future = executorService.submit(callable);
try {
String result = future.get(30, TimeUnit.SECONDS);
System.out.println("Result: " + result);
}
catch (TimeoutException e) {
System.out.println("Timeout");
future.cancel(true);
}
There's a lot more to the concurrency API, see the package java.util.concurrent.

Could you describe what exactly do you want?
Just stopping of execution method you can use return, System.exit(), last stop VM.
By time, just check time and return from method. Also, you can try some reflection hacks...
By the way, these are just a imagination if you will describe in more words what do you need I will help you.

Try:
public static void wait(int n){
long time0,time1;
time0=System.currentTimeMillis();
do{
time1=System.currentTimeMillis();
}
while (time1-time0<n);
}
I think that works. If you invoke this method, pass it with the amount of time in milliseconds you want the program to wait as parameter.
Good luck!

Related

ExecutorService for Do-While Loop in Java

I am new to concurrency and I was trying to implement executor service concurrency for a do-while loop. But I always run into RejectedExecutionException
Here is my sample code:
do {
Future<Void> future = executor.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
// action
return null;
}
});
futures.add(future);
executor.shutdown();
for (Future<Void> future : futures) {
try {
future.get();
}
catch (InterruptedException e) {
throw new IOException(e)
}
}
}
while (true);
But this seems incorrect. I think I am calling the shutdown at the wrong place. Can anyone please help me implement Executor Service in a do-while loop correctly. Thanks.
ExecutorService.shutdown() stops the ExecutorService from accepting anymore jobs. It should be called when you're done submitting jobs.
Also Future.get() is a blocking method, which means it will block the execution of current thread and next iteration of loop will not continue unless this future (on which the get is called) returns. This will happen in every iteration, which makes the code non parallel.
You can use a CountDownLatch to wait for all the jobs to return.
Following is the correct code.
final List<Object> results = Collections.synchronizedList(new ArrayList<Object>());
final CountDownLatch latch = new CountDownLatch(10);//suppose you'll have 10 futures
do {
Future<Void> future = executor.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
// action
latch.countDown();//decrease the latch count
results.add(result); // some result
return null;
}
});
futures.add(future);
} while (true);
executor.shutdown();
latch.await(); //This will block till latch.countDown() has been called 10 times.
//Now results has all the outputs, do what you want with them.
Also if you're working with Java 8 then you can take a look at this answer https://stackoverflow.com/a/36261808/5343269
You're right, the shutdown method is not being called at the correct time. The ExecutorService will not accept tasks after shutdown is called (unless you implement your own version that does).
You should call shutdown after you've already submitted all tasks to the executor, so in this case, somewhere after the do-while loop.
From ThreadPoolExecutor documentation:
Rejected tasks
New tasks submitted in method execute(Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated.
In either case, the execute method invokes the RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler
From your code, it's clearly evident that you are calling shutdown() first and submitting the tasks later.
On a different note, refer to this related SE question for right way of shutting down ExecutorService:
ExecutorService's shutdown() doesn't wait until all threads will be finished

Java: Waiting on Get Method of ScheduledFuture

Please consider the following code:
public static void main(String... args) throws InterruptedException, ExecutionException {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> future =
executor.scheduleAtFixedRate(Dummy::iterate,
0,
1,
TimeUnit.SECONDS);
TimeUnit.MILLISECONDS.sleep(1500);
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MILLISECONDS);
System.out.println("Getting the future...");
future.get();
System.out.println("Got the future...");
System.out.println("Finished");
}
private static void iterate(){
System.out.println("Iterating... counter is: " + counter++);
try {
TimeUnit.MILLISECONDS.sleep(900);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Note that the executor.awaitTermination(...) command future.get() command are happening after 1500 ms, meaning in the middle of the iterate() method.
This means that awaitTermination(...) will return false because the scheduled task hasn't finsihed yet.
Now, future.get() will wait forever. The task will finish and the service won't start other tasks, but yet the get() will never return.
A workaround is asking the future for isDone(), and only if it is done, asking for the result.
My question is what exactly is happening?
Looks like that if shutDown() happens in the during an iteration, the ScheduledThreadPool will somehow halt and, meaning there will be no future available. So why is this happening? I have looked at the documentation but couldn't find any reference indicating this issue. Is it possible that such scenario causes a future to not done, and later for the future to not be available?
If you replace your :
future.get();
to something like:
future.get(2000,TimeUnit.MILLISECONDS);
Then you see java.util.concurrent.TimeoutException exception ocuur.
and this Exception thrown when a blocking operation times out. Blocking operations for which a timeout is specified need a means to indicate that the timeout has occurred. For many such operations it is possible to return a value that indicates timeout; when that is not possible or desirable then TimeoutException should be declared and thrown.

Not calling get on list of futures

I'm using a global Executor service with some fixed thread pool size. We have bunch of related tasks that we submit for execution and wait on list of futures.
Recently, we faced a high CPU utilization issue and on debugging I found that an exception occurred while calling get() on one of the item in list of futures. Current, we iterate over the list and there is a try catch surrounding the whole loop.
try{
List<Result> results = new ArrayList<>()
for(Future<Result> futureResult: futureResults{
Result result = futureResult.get();
results.add(result);
}
} catch(Exception e){
throw new InternalServiceException(e);
}
//Do something with results
Wanted to know the behaviour of other threads if get is never called on some of the items in future. I tried searching but was not able to find anything.
Also, can this behaviour trigger high CPU utilization ?
http://www.journaldev.com/1650/java-futuretask-example-program
I would still check if the future isDone as in the example above.
If you need to run other operations or want to utilize the CPU better then I would put the collector in a separate thread and perhaps just poll for results every minute or so.
Could be scheduled or handled by Thread.sleep.
Executors class provides various methods to execute Callable in a thread pool. Since callable tasks run in parallel, we have to wait for the returned Object.
Callable tasks return java.util.concurrent.Future object. Using Future we can find out the status of the Callable task and get the returned Object.
It provides get() method that can wait for the Callable to finish and then return the result.
There is an overloaded version of get() method where we can specify the time to wait for the result, it’s useful to avoid current thread getting blocked for longer time.
Future provides cancel() method to cancel the associated Callable task. There are isDone() and isCancelled() methods to find out the current status of associated Callable task.
Here is a simple example of Callable task that returns the name of thread executing the task after some random time.
We are using Executor framework to execute 10 tasks in parallel and use Future to get the result of the submitted tasks.
public class FutureObjectTest implements Callable<String>{
#Override
public String call() throws Exception {
long waitTime = (long) (Math.random()*10000);
System.out.println(Thread.currentThread().getName() + " waiting time in MILISECONDS " + waitTime);
Thread.sleep(waitTime);
return Thread.currentThread().getName() + " exiting call method.";
}
public static void main(String [] args){
List<Future<String>> futureObjectList = new ArrayList<Future<String>>();
ExecutorService executorService = Executors.newFixedThreadPool(5);
Callable<String> futureObjectTest = new FutureObjectTest();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("Starting get method of wait");
////////////get(Timeout) method///////
futureObjectList.clear();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
executorService.shutdown();
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get(2000,TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
}
}
}

how can i make a thread sleep for a while and then start working again?

I have the following code:
public void run()
{
try
{
logger.info("Looking for new tasks to fetch... ");
// definitions ..
for(Task t: tasks)
{
logger.info(" Task " + t.getId() + " is being fetched ");
// processing ... fetching task info from db using some methods
}
Thread.sleep(FREQUENCY);
//t.start();
} catch (Exception e)
{
logger.info("FetcherThread interrupted: "+e.getMessage());
}
}
I'm trying to make the thread to sleep for a specific time "FREQUENCY" and then work again. when I execute this code in eclipse, the thread works only once and then nothing happens and process terminates. If I remove the comment from the statement: t.start(), I get "FetcherThread interrupted: null".
Can anyone tell me where I'm going wrong?
N.B.: I want the thread to be working all the time, but fetching on periods (say every 5 minutes)
You're missing any sort of loop in that code.
It seems that the thread is actually doing what you tell it to do: it runs all the tasks, then sleeps for a bit - then it has no more work to do, and so exits. There are several ways to address this, in ascending order of complexity and correctness:
The simple (and naive) way to address this is to wrap the try-catch block in an infinite loop (while(true) { ... }). This way after the thread finishes sleeping, it will loop back to the top and process all the tasks again.
However this isn't ideal, as it's basically impossible to stop the thread. A better approach is to declare a boolean field (e.g. boolean running = true;), and change the loop to while(running). This way, you have a way to make the thread terminate (e.g. expose a method that sets running to false.) See Sun's Why is Thread.stop() deprecated article for a longer explanation of this.
And taking a step further back, you may be trying to do this at too low a level. Sleeping and scheduling isn't really part of the job of your Runnable. The actual solution I would adopt is to strip out the sleeping, so that you have a Runnable implementation that processes all the tasks and then terminates. Then I would create a ScheduledExecutorService, and submit the "vanilla" runnable to the executor - this way it's the job of the executor to run the task periodically.
The last solution is ideal from an engineering perspective. You have a class that simply runs the job once and exits - this can be used in other contexts whenever you want to run the job, and composes very well. You have an executor service whose job is the scheduling of arbitrary tasks - again, you can pass different types of Runnable or Callable to this in future, and it will do the scheduling bit just as well. And possibly the best part of all, is that you don't have to write any of the scheduling stuff yourself, but can use a class in the standard library which specifically does this all for you (and hence is likely to have the majority of bugs already ironed out, unlike home-grown concurrency code).
Task scheduling has first-class support in Java, don't reinvent it. In fact, there are two implementations: Timer (old-school) and ScheduledExecutorService (new). Read up on them and design your app aroud them.
Try executing the task on a different thread.
You need some kind of loop to repeat your workflow. How shall the control flow get back to the fetching part?
You can put the code inside a loop.( May be while)
while(condition) // you can make it while(true) if you want it to run infinitely.
{
for(Task t: tasks)
{
logger.info(" Task " + t.getId() + " is being fetched ");
// processing ... fetching task info from db using some methods
}
Thread.sleep(FREQUENCY);
}
Whats happening in your case its running the Task loop then sleeping for some time and exiting the thread.
Put the thread in a loop as others have mentioned here.
I would like to add that calling Thread.start more than once is illegal and that is why you get an exception.
If you would like to spawn multiple thread create one Thread object per thread you want to start.
See http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#start()
public void run()
{
while (keepRunning) {
try
{
logger.info("Looking for new tasks to fetch... ");
// definitions ..
for(Task t: tasks)
{
logger.info(" Task " + t.getId() + " is being fetched ");
// processing ... fetching task info from db using some methods
t.start();
}
Thread.sleep(FREQUENCY);
} catch (Exception e) {
keepRunning = false;
logger.info("FetcherThread interrupted: "+e.getMessage());
}
}
}
Add a member call keepRunning to your main thread and implement an accessor method for setting it to false (from wherever you need to stop the thread from executing the tasks)
You need to put the sleep in an infinite loop (or withing some condition specifying uptill when you want to sleep). As of now the sleep method is invoked at the end of the run method and behavior you observe is correct.
The following demo code will print "Sleep" on the console after sleeping for a second. Hope it helps.
import java.util.concurrent.TimeUnit;
public class Test implements Runnable {
/**
* #param args
*/
public static void main(String[] args) {
Test t = new Test();
Thread thread = new Thread(t);
thread.start();
}
public void run() {
try {
// logger.info("Looking for new tasks to fetch... ");
// definitions ..
// for(Task t: tasks)
// {
// logger.info(" Task " + t.getId() + " is being fetched ");
// // processing ... fetching task info from db using some methods
// }
while (true) { // your condition here
TimeUnit.SECONDS.sleep(1);
System.out.println("Sleep");
}
// t.start();
} catch (Exception e) {
// logger.info("FetcherThread interrupted: "+e.getMessage());
}
}
}
You could try ScheduledExecutorService (Javadoc).
And us it's scheduleAtFixedRate, which:
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.

On FutureTask, finally and TimeoutExceptions in Java

I'm trying to understand how to ensure that a specific action completes in a certain amount of time. Seems like a simple job for java's new util.concurrent library. However, this task claims a connection to the database and I want to be sure that it properly releases that connection upon timeout.
so to call the service:
int resultCount = -1;
ExecutorService executor = null;
try {
executor = Executors.newSingleThreadExecutor();
FutureTask<Integer> task = new CopyTask<Integer>();
executor.execute(task);
try {
resultCount = task.get(2, TimeUnit.MINUTES);
} catch (Exception e) {
LOGGER.fatal("Migrate Events job crashed.", e);
task.cancel(true);
return;
}
} finally {
if (executor != null) {
executor.shutdown();
}
The task itself simply wrapps a callable, here is the call method:
#Override
public Integer call() throws Exception {
Session session = null;
try {
session = getSession();
... execute sql against sesssion ...
}
} finally {
if (session != null) {
session.release();
}
}
}
So, my question for those who've made it this far, is: Is session.release() garaunteed to be called in the case that the task fails due to a TimeoutException? I postulate that it is no, but I would love to be proven wrong.
Thanks
edit: The problem I'm having is that occasionally the sql in question is not finishing due to wierd db problems. So, what I want to do is simply close the connection, let the db rollback the transaction, get some rest and reattempt this at a later time. So I'm treating the get(...) as if it were like killing the thead. Is that wrong?
When you call task.get() with a timeout, that timeout only applies to the attempt to obtain the results (in your current thread), not the calculation itself (in the worker thread). Hence your problem here; if a worker thread gets into some state from which it will never return, then the timeout simply ensures that your polling code will keep running but will do nothing to affect the worker.
Your call to task.cancel(true) in the catch block is what I was initially going to suggest, and this is good coding practice. Unfortunately this only sets a flag on the thread that may/should be checked by well-behaved long-running, cancellable tasks, but it doesn't take any direct action on the other thread. If the SQL executing methods don't declare that they throw InterruptedException, then they aren't going to check this flag and aren't going to be interruptable via the typical Java mechanism.
Really all of this comes down to the fact that the code in the worker thread must support some mechanism of stopping itself if it's run for too long. Supporting the standard interrupt mechanism is one way of doing this; checking some boolean flag intermittently, or other bespoke alternatives, would work too. However there is no guaranteed way to cause another thread to return (short of Thread.stop, which is deprecated for good reason). You need to coordinate with the running code to signal it to stop in a way that it will notice.
In this particular case, I expect there are probably some parameters you could set on the DB connection so that the SQL calls will time out after a given period, meaning that control returns to your Java code (probably with some exception) and so the finally block gets called. If not, i.e. there's no way to make the database call (such as PreparedStatement.execute()) return control after some predetermined time, then you'll need to spawn an extra thread within your Callable that can monitor a timeout and forcibly close the connection/session if it expires. This isn't very nice though and your code will be a lot cleaner if you can get the SQL calls to cooperate.
(So ironically despite you supplying a good amount of code to support this question, the really important part is the bit you redacted: "... execute sql against sesssion ..." :-))
You cannot interrupt a thread from the outside, so the timeout will have no effect on the code down in the JDBC layer (perhaps even over in JNI-land somewhere.) Presumably eventually the SQL work will end and the session.release() will happen, but that may be long after the end of your timeout.
The finally block will eventually execute.
When your Task takes longer then 2 minutes, a TimeoutException is thrown but the actual thread continues to perform it's work and eventually it will call the finally block. Even if you cancel the task and force an interrupt, the finally block will be called.
Here's a small example based in your code. You can test these situations:
public static void main(String[] args) {
int resultCount = -1;
ExecutorService executor = null;
try {
executor = Executors.newSingleThreadExecutor();
FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
#Override
public Integer call() throws Exception {
try {
Thread.sleep(10000);
return 1;
} finally {
System.out.println("FINALLY CALLED!!!");
}
}
});
executor.execute(task);
try {
resultCount = task.get(1000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
System.out.println("Migrate Events job crashed: " + e.getMessage());
task.cancel(true);
return;
}
} finally {
if (executor != null) {
executor.shutdown();
}
}
}
Your example says:
copyRecords.cancel(true);
I assume this was meant to say:
task.cancel(true);
Your finally block will be called assuming that the contents of the try block are interruptible. Some operations are (like wait()), some operations are not (like InputStream#read()). It all depends on the operation that that the code is blocking on when the task is interrupted.

Categories

Resources