Reputation: 479
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;
}
}
Upvotes: 1
Views: 525
Reputation: 27115
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.
Upvotes: 0
Reputation: 1843
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.
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.
Upvotes: 3
Reputation: 3430
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...)
Upvotes: 0
Reputation: 858
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
Upvotes: 0