1

I have a Service which is running on a thread. When I need the thread to stop running I am using this code
this.serviceThread.interrupt(); this.serviceThread = null;

At some point I need to recreate the thread again

this.serviceThread = new Thread() 
        {
            public void run() 
            {
                TheService.this.serviceProcessThread();
            }
        };
        this.serviceThread.start();

However, it still seems like the previous Thread is still alive and running because it is listed in the list of currently running threads. This list just keeps growing every time I try to stop and create a new thread. Is this normal? Is there anyway I can get rid of those old threads?

I mainly just want to know if that list of threads means they are still there and, if so, how can I remove them. Thanks!

EDIT: This is how I am handling running/stopping the thread

public void startProcessThread()
{
    this.shutdown = false;
    this.serviceThread = new Thread() 
    {
        public void run() 
        {
            TheService.this.serviceProcessThread();
        }
    };
    this.serviceThread.start();
}
private void serviceProcessThread()
{
    do 
    {
        try 
        {
            this.getCommands();

            if (this.tasks.size() > 0)
                this.processTasks();

            if (!this.shutdown)
            {
                Thread.sleep(ServiceSleepTime);
            }
        }
        catch (Exception e) 
        {
            this.logException("serviceProcessThread", e);
        }
    } 
    while (!this.shutdown);
    if(this.serviceThread != null)
    {
        this.serviceThread.interrupt();
        this.serviceThread = null;

    }

}
Programmer
  • 459
  • 5
  • 20
  • 1
    From [What does java.lang.Thread.interrupt() do?](http://stackoverflow.com/questions/3590000/what-does-java-lang-thread-interrupt-do) "Thread.interrupt() sets the interrupted status/flag of the target thread. Then code running in that target thread **MAY** poll the interrupted status and handle it appropriately. Some methods that block such as Object.wait() may consume the interrupted status immediately and throw an appropriate exception (usually InterruptedException)" – Richard Tingle Aug 07 '14 at 14:49
  • This sounds like an ideal time to use a thread pool. – TEK Aug 07 '14 at 14:49
  • So by calling .interupt() and making it null, it won't ever actually get rid of the thread? I keep looking for the appropriate method to do this but all I see is people interrupting/stopping the thread and creating a new one. – Programmer Aug 07 '14 at 14:54
  • @Hooplehead24 Do you have control of the code being run in the thread. If so, use William F. Jameson's answer to make sure it *is* interuptable – Richard Tingle Aug 07 '14 at 15:00
  • I added new code for your reference. I THINK I am doing it right but hopefully someone can tell me if I am exiting it incorrectly. I'm not sure if it is completely interruptible based on how I am handling it. – Programmer Aug 07 '14 at 15:04
  • The code you have added looks a lot like an attempt at a reimplementation of the `ScheduledExecutorService`. You should use the JDK implementation instead. As far as stopping the `serviceThread`, the snippet you provide is irrelevant: you must show `serviceThread`'s implementation. – William F. Jameson Aug 07 '14 at 15:04
  • I added the complete implementation of the serviceThread. I will look into ScheduledExecutorService. – Programmer Aug 07 '14 at 15:11

4 Answers4

3

The first thing you must face is that a thread cannot be forcibly stopped without potentially adverse effects on the whole Java process. This is why Java introduced the mechanism of thread interruption: a common, cooperative mechanism to gracefully stop a thread.

The cooperative aspect is key: whatever you do in your thread's implementation code, you must ensure that it is interruptible. A short checklist:

  • if you have blocking calls (those which arrest the thread while waiting on a condition), they must be interruptible (basically, declare to throw InterruptedException);

  • you must catch and handle the InterruptedException properly, by performing any due cleanup and making the top-level run method return;

  • if you have implemented a long-running loop, you must ensure that it checks the Thread.currentThread().isInterrupted() flag periodically, and breaks if the thread was interrupted;

  • if you cede control any 3rd party code, make sure that this code is interruptible.

Also keep in mind that the lifecycle of Thread as a Java object has nothing to do with the actual thread of execution. Thread is merely a handle object which lets you manage the underlying thread, much as a File is a handle for a filesystem entity. Setting a File reference to null does not delete the file from the system.

Update

Your implementation code could be fixed by not swallowing the InterruptedException.

    try {
        this.getCommands();
        if (this.tasks.size() > 0)
            this.processTasks();
        if (!this.shutdown)
            Thread.sleep(ServiceSleepTime);
    }
    catch (InterruptedException e) {
        this.shutdown = true;
    }
    catch (Exception e) 
    {
        this.logException("serviceProcessThread", e);
    }

Also, this part is redundant:

if(this.serviceThread != null)
{
    this.serviceThread.interrupt();
    this.serviceThread = null;

}

Here you attempt to interrupt your own (current) thread. The point was that the thread should be interrupted from another thread.

Community
  • 1
  • 1
William F. Jameson
  • 1,833
  • 9
  • 14
  • So I added `while (!this.shutdown && !this.serviceThread.isInterrupted());` and it is removing those threads properly. However, I am getting `InteruptedException`. – Programmer Aug 07 '14 at 15:16
  • The thread must check the flag *from the inside*. You are checking it from the outside (from another thread). – William F. Jameson Aug 07 '14 at 15:21
  • That was it! By handling the `InterruptedException` it now works and properly gets rid of the threads. Thank you! – Programmer Aug 07 '14 at 15:28
0

The .interrupt() does not cause a thread to exit unless you check for the interrupted status, via something like:

if (Thread.interrupted()) {
    skipRemainingActions();
}

or

while(!Thread.interrupted())
{
    doStuff();
}

if there is still code to run in the thread, it will continue to run, even if you call interrupt on it

user2813274
  • 838
  • 1
  • 9
  • 22
0

If you are not doing anything concurrently what you need to do this is create a single thread and post task to it using handler.

There is very good article here:http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/

You can also use AsyncTask to do the same thing-http://developer.android.com/reference/android/os/AsyncTask.html

If you have task running concurrently you can use executeOnExecutor() method of AsyncTask refer-http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params...)

rupesh jain
  • 3,410
  • 1
  • 14
  • 22
0

Not a solution to your problem but, this does not do what you think it does:

Thread t = new Thread(new MyRunnableTask());
t.start();
t = null;

The t.start() call creates the new thread. NOTE: I said "thread", not "Thread". A (big T) Thread is an object that can be used to create and manage a (little t) thread. Once the (little t) thread is started, it has a life of its own.

When you set the local variable t to null, all you are doing is erasing your reference to the (big T) Thread object that manages the (little t) thread. The (big T) Thread object is unaffected: It will continue to exist as long as the (little t) thread is running. The (little t) thread is unaffected: It will continue to do whatever it does. The only thing that changes when you set t to null, is that you no longer have any control over the new thread.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57