2

I want a task to run at scheduled interval and timeout if it does not complete in required time and continue further iteration.

I have gone through the following answers, but it doesn't address my problem..

How do you kill a Thread in Java?

ExecutorService that interrupts tasks after a timeout

Consider the following case

    BasicThreadFactory collectionFactory = new BasicThreadFactory.Builder()
            .namingPattern("CollectionExecutor-%d")
            .build();
    // thread pool size is set 2
    // 1-for scheduler thread which runs task and tracks timeout
    // 2-for task itself
    ScheduledExecutorService collectionExecuter = 
            Executors.newScheduledThreadPool(2, collectionFactory);
    // fires collection every minute and if it is in between execution during
    // scheduled time then waits for completion and executes immediately
    // after it

    //my task:
    Runnable runnable= new Runnable() {

        @Override
            public void run() {
        try {
            System.out.println("Executed started");
            Thread.sleep(2000);
            System.out.println("Executed after .get method call.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            Thread.sleep(20000);
            System.out.println("Executed even after .cancel method " +
                    "call (I want this to avoid this.)");
        } catch (Exception e) {
            e.printStackTrace();
        }               
    }
};

Above task should run with an interval of 3 sec and stop if it takes more than 1 sec...Consider It is not possible to have complete task in single try catch block, now how could I stop the task to wait further in next sleep(20000) and continue with next iteration.

    collectionExecuter.scheduleAtFixedRate(new Runnable() {//scheduler thread
        @Override
        public void run() {
            try {
                Future<?> future = collectionExecuter.submit(runnable);
                try {
                    future.get(1, TimeUnit.SECONDS);

                } catch (Exception e) {
                    future.cancel(true);
                    System.out.println("Collection thread did not " +
                           "completed in 1 Sec.Thread Interrupted");
                }
            } catch (Exception e) {
                System.out.println("Unable to start Collection Thread");
            }
        }
    }, 0, 3, TimeUnit.SECONDS);
}
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
atul
  • 56
  • 9
  • Have the task check some flag after the long sleep and return if that flag indicates the task should stop. – Thomas Aug 28 '18 at 10:57
  • Why did those other questions not help? I see several answers there that would achieve the behavior you desire. – Max Vollmer Aug 28 '18 at 10:59
  • @Thomas sleep could a DB call which has a read latency of let say 20 sec. – atul Aug 28 '18 at 10:59
  • If your problem is caused by blocking IO calls, your question should be about asynchronous IO implementations, not about killing threads. See this for example: https://stackoverflow.com/questions/4087696/is-asynchronous-jdbc-call-possible – Max Vollmer Aug 28 '18 at 11:01
  • @MaxVollmer the answers mention the use of .cancel interrupt signal but that would not ensure you that your task is stopped.. As per Java docs .cancel method Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. What should be done in the given scenario. – atul Aug 28 '18 at 11:04
  • There are 14 answers on the first and 8 answers on the second question you linked, which makes a total of 22 answers. They do not all talk about interrupts. Yes, there are a few answers that talk about interrupts, but there are plenty of answers that provide alternatives. – Max Vollmer Aug 28 '18 at 11:06
  • 1
    All InterruptedException catch should stop properly your thread, Ever relaunch currentThread.interrupt(), or in your case, simply return. When you catch this exception, you also catch the interrupt signal. a good answer on this: https://stackoverflow.com/questions/3976344/handling-interruptedexception-in-java – pdem Aug 28 '18 at 11:07
  • @MaxVollmer I have a strict timeout for my task...there can be multiple try catch blocks in my code and if in any block the timeout is reached no futher execution should happen...Although Having a flag in rest of the blocks will achieve this..but I want to know the correct implementation of this case. – atul Aug 28 '18 at 11:08
  • @pdem returning in case of interrupts by handling the interrupt exception separately will do the job but there can be a scenario when Interrupt exception is caused from a different piece of code..and in that case next block should be executed. – atul Aug 28 '18 at 11:19
  • Don't do it. Even if you kill a DB connection because a query is taking too long, the query will continue to run on the server side. You will continuously repeat the bad query until your backend locks up. Better fix the query than to interrupt threads/connections etc. – rustyx Aug 28 '18 at 11:26
  • @atul The full answer is here https://stackoverflow.com/questions/5241822/is-there-a-good-way-to-forcefully-stop-a-java-thread read the interruptedexception management good practice: All good piece of code should never catch an interruptedException without exiting by a mean or another. You just can't interrupt a Thread that doesn't respect theses pratices – pdem Aug 28 '18 at 11:26

0 Answers0