Fi Horan
Fi Horan

Reputation: 512

Java - Close a thread with 'return' not working

I have the following code in a class which contains my main method

ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable formatConcentration = new formatConcentration(87);
executor.execute(formatConcentration);
System.out.println("Called an instance of formatConcentration");
while (!executor.isTerminated())
{
    //stay Alive
    Thread.sleep(1000);
    System.out.println("Still alive");
}
System.out.println("Program successfully finished");
return;

This creates an instance of formatConcentration class. The code for which is the following (I've taken all of my functionality out for the sake of the example).

public class formatConcentration extends Thread{
    private int numberOfNewRows;

    formatConcentration(int rows)
    {
        this.numberOfNewRows = rows;
    }
    public void run() {

        System.out.println("Running the Formatting Script");
        final int numberOfNewRegistered = this.numberOfNewRows;
        try 
        {
            System.out.println("Finished formatting");
        }//end of try
        catch (Exception e1) 
        {
            log.log(e1.toString());
            log.closeLog() ;
            System.exit(1) ;
        }
        System.out.println("Still Finished formatting");
        return;
    }
}

My problem is that once return is invoked it does not terminate the thread.

I have done quite a lot of looking around and as far as I can tell this should be fine but I would imagine that I'm overlooking something small and would appreciate fresh eyes on the problem.

Or if someone has a suggestion of how to kill the thread from inside the run(){} method I would greatly appreciate it (preferably not by setting a variable that I'll check in the main class but if that's how I have to do it so be it) as I know that once it reaches the return statement it's finished and no longer need any reference to variables created in run().

The output generated to the console is as follows:

Called an instance of formatConcentration
Running the Formatting Script
Finished formatting
Still Finished formatting
Still alive
Still alive
Still alive
Still alive
Still alive
etc.

Upvotes: 0

Views: 1053

Answers (3)

Hakuna Matata
Hakuna Matata

Reputation: 761

ExecutorService is mainly used to delegate your jobs to separte workers. Using this only most of the Connection pooling libs have been created. So this service will be initiated whenever your application is started and will be closed (manually) by your application's closing method.

In your program you should write a code to check the executor service's status,

Is any workers are currently working... If no workers are in busy mode then just stop accepting any further tasks.

From javadocs see the sample shutdown code,

The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks:

void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

Hope it will give some information to you.

Upvotes: 0

Veselin Davidov
Veselin Davidov

Reputation: 7081

ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable formatConcentration = new formatConcentration(87);
executor.execute(formatConcentration);
System.out.println("Called an instance of formatConcentration");
executor.shutdown();
while (!executor.isTerminated())
{
    //stay Alive
    Thread.sleep(1000);
    System.out.println("Still alive");
}
System.out.println("Program successfully finished");
return;

Another simpler way to do it would be :

   ExecutorService executor = Executors.newFixedThreadPool(1);
    Runnable formatConcentration = new formatConcentration(87);
    executor.execute(formatConcentration);
    executor.shutdown();
    try {
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Executor awaitTermination method substitutes your loop.

Upvotes: 0

Ray
Ray

Reputation: 3201

You never shutdown the executor. From the Javadocs for isTerminated:

Returns true if all tasks have completed following shut down. Note that isTerminated is never true unless either shutdown or shutdownNow was called first.

As long as you don't shutdown the executor, you can submit new tasks to it for execution. isTerminated does not check the state of the submitted tasks, it checks the state of the ExecutorService itself.

Upvotes: 2

Related Questions