Java 8: Kill/Stop a thread after certain period of time

Viewed 1221

I have a java 8 based project which performs a certain function on a url. I need to modify the code snippet below so that it is capable of killing the thread/process running and run the next instance after a certain period of time irrespective of current process status.

I tried the following techniques to implement the thread kill procedure:

  • Executor service
  • Timer Task
  • Multithreaded thread kill

The code snippet for my most recent attempt is linked below.

@SuppressWarnings("static-access")
public static void main(String[] args) {
//fetch url from the txt file
    List<String> careerUrls = getCareerUrls();
    int a = 0;
    DBConnection ds = null;
    ds = DBConnection.getInstance();
    try (java.sql.Connection con = ds.getConnection()) {
        //read a single Url
        for (String url : careerUrls) {
            int c = a++;

            ExecutorService executor = Executors.newFixedThreadPool(3);

            Future<?> future = executor.submit(new Runnable() {
                @Override
                // <-- job processing
                public void run() {
                    long end_time = System.currentTimeMillis() + 10000;

                    System.out.println("STARTED PROCESSING URL: " + url);
                    jobareaDeciderSample w = new jobareaDeciderSample();
                    w.mainSample(url, c, con);

                }
            });
            // <-- reject all further submissions
            executor.shutdown();
            try {
                future.get(120, TimeUnit.SECONDS); // <-- wait 2 Minutes to finish
            } catch (InterruptedException e) { // <-- possible error cases
                System.out.println("job was interrupted");
                future.cancel(true);
                Thread.currentThread().interrupt();
                ;
            } catch (ExecutionException e) {
                System.out.println("caught exception: " + e.getCause());
            } catch (TimeoutException e) {
                System.out.println("timeout");
                future.cancel(true);

            }

            // wait all unfinished tasks for 2 sec
            if (!executor.awaitTermination(0, TimeUnit.SECONDS)) {
                // force them to quit by interrupting
                executor.shutdownNow();
            }
        }

    } catch (Exception e) {
        LOGGER.error(e);
    }

}
1 Answers

You are correct with your approach. calling cancel(true); on future is the right way to stop this task.

You have another problem- you cannot just stop a thread. (well you can, using stop() in thread class, but you should never do this).

cancel(true); sends information to the thread, that it should be stopped. Some java classes are responding to this information and throw interrupted exception. But some dont. You have to modify your task code, to check if Thread.currentThread().isInterrupted(), and if so, stop execution.

This is something you have to do in your code, which you call by

  jobareaDeciderSample w = new jobareaDeciderSample();
                    w.mainSample(url, c, con);

You should do this in some long time spinning code, if you said you do some stuff with url, you should do it in your while loop, where you download information for the web. In other words, do this check only when your code spends 99% of the time.

Also you are calling

        Thread.currentThread().interrupt();

in your main thread, this does not do anything for you, as if you want to quit current thread, you can just call return

Related