它已停止运行后,线程不会被删除(Thread isn't removed after it

2019-10-20 16:00发布

我有是在一个线程中运行的服务。 当我需要的线程停止运行,我使用此代码
this.serviceThread.interrupt(); this.serviceThread = null;

在某些时候,我需要再次重新创建线程

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

然而,它似乎仍然因为它是在当前运行的线程的列表中列出像以前的主题仍然活着并运行。 这份名单只是不断每次我试图阻止,并创建一个新的线程时间增长。 这是正常的吗? 反正我有可以摆脱那些老的线程?

我主要就是想知道,如果线程该名单意味着他们仍然存在,如果是这样,我怎么能删除它们。 谢谢!

编辑:这是怎么了处理运行/停止线程

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;

    }

}

Answer 1:

你必须面对的第一件事情是,一个线程不能强行没有对整个Java进程的潜在不利影响停止。 这就是为什么Java的线程介绍中断的机制:一个共同的, 合作机制,正常停止一个线程。

合作方面是关键:无论你在你的线程的实现代码做什么,你必须确保它是中断的。 一个简短的清单:

  • 如果你有阻塞调用(那些逮捕线,同时在条件等),他们必须中断(基本上,申报抛出InterruptedException );

  • 你必须捕获并处理InterruptedException正常,应通过执行任何清除因,使顶层的run方式回报;

  • 如果你已经实现了长期运行的循环,你必须确保它检查Thread.currentThread().isInterrupted()定期标志,和休息,如果线程被中断;

  • 如果你放弃控制任何第三方代码,请确保此代码是中断的。

也请记住,生命周期Thread作为一个Java对象无关与执行的实际线程。 Thread仅仅是处理对象,它可以让你管理底层的线程,就像一个File是一个文件系统实体的句柄。 设置一个File引用null不从系统中删除该文件。

更新

你的实现代码可以通过不吞咽的固定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);
    }

此外,这部分是多余的:

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

}

在这里,您试图中断自己(当前)线程。 问题的关键是,线程应该从另一个线程中断。



Answer 2:

该.interrupt()不会导致线程退出,除非你检查中断状态,通过这样的:

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

要么

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

如果还有代码在线程中运行,它会继续运行,即使你调用中断就可以了



Answer 3:

如果你没有做任何事情同时你需要做什么这是创建一个单独的线程和使用处理后的任务吧。

有很好的文章在这里: http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/

您还可以使用的AsyncTask做同样的东西─ http://developer.android.com/reference/android/os/AsyncTask.html

如果你有任务同时运行,你可以使用的AsyncTask refer-的executeOnExecutor()方法http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor ,则params .. 。)



Answer 4:

不是你的问题的解决方案,但是,这并没有做什么,你认为它的作用:

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

t.start()调用创建新的线程。 注意:我说的“线程”,而不是“线程”。 A(大T)线程是可用于创建和管理一个(小T)线程的对象。 一旦(小T)线程启动,它有它自己的生命。

当您设置局部变量t为null,所有你做的是消除你参考到管理(小T)的线程(大T)的Thread对象。 在(大T)Thread对象是未受影响:它将继续只要(小T)线程运行存在。 该(小T)线程不受影响:它会继续尽一切可能做。 当您设置唯一改变的t为null,是你不再有在新线程的任何控制。



文章来源: Thread isn't removed after it has stopped running