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;
}
}
The .interrupt() does not cause a thread to exit unless you check for the interrupted status, via something like:
or
if there is still code to run in the thread, it will continue to run, even if you call interrupt on it
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...)
Not a solution to your problem but, this does not do what you think it does:
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 sett
to null, is that you no longer have any control over the new thread.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-levelrun
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 aFile
is a handle for a filesystem entity. Setting aFile
reference tonull
does not delete the file from the system.Update
Your implementation code could be fixed by not swallowing the
InterruptedException
.Also, this part is redundant:
Here you attempt to interrupt your own (current) thread. The point was that the thread should be interrupted from another thread.