Thread isn't removed after it has stopped runn

2019-08-08 19:58发布

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;

    }

}

4条回答
Ridiculous、
2楼-- · 2019-08-08 20:33

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

查看更多
做自己的国王
3楼-- · 2019-08-08 20:33

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...)

查看更多
Rolldiameter
4楼-- · 2019-08-08 20:36

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.

查看更多
叛逆
5楼-- · 2019-08-08 20:48

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.

查看更多
登录 后发表回答