我在stackoverflow上看到了一些帖子,并阅读了oracle在销毁线程时发布的教程。根据我的理解,一旦你start()
一个线程,就不能使用stop()
删除该线程。不是实际从调度程序中删除线程,而是建议无限期地创建线程sleep()
。这是正确的吗?
这也让我想到了我的下一个问题,这就是为什么人们使用thread pools?.
而不是“休眠”一个线程,使用该线程处理其他作业而不是创建新线程更加足够。如果我对multi-thread
管理层的理解是正确的,请告诉我。没有理由认为Java不允许以安全的方式完全删除thread
。
答案 0 :(得分:3)
一旦线程一旦启动(或使其无限期地睡眠)强行停止线程通常被认为是一个非常糟糕的主意,因为线程将无法清除它已获取的任何资源。例如,如果一个线程获得了一个锁并且被无限期地强行杀死或睡眠,那么锁将不会被释放并且随后可能发生死锁。同样,如果线程正在对数据结构进行更改并提前终止,则数据结构可能处于损坏状态,从而导致严重问题。
在Java中停止线程的最佳方法是中断线程并告诉它需要尽快尝试关闭。这样,线程可以尝试停止正在执行的操作并在关闭之前释放所有资源。换句话说,你请求线程关闭,而不是强行杀死它。
这与线程池存在的原因无关。线程池很有用,因为创建或销毁线程通常会产生一些开销,因为跟踪线程的状态和进度需要内部JVM或OS级别的簿记。线程池使得回收线程成为可能,让它们通过让线程休眠直到任务准备好,然后唤醒并执行任务来执行不同的任务。这可能比产生一个新线程,自己执行任务,然后拆除线程要快得多。
希望这有帮助!
答案 1 :(得分:1)
正如templatetypedef所提到的,你不应该强行停止一个线程,你应该向一个线程发出信号停止。例如,每当你的线程阻塞时,它应该在while循环中完成,它测试它阻塞的条件,以及退出的条件:
while (!condition && !stop) {
try {
someBlockingFunction(); // A lock, take on a BlockingQueue, etc.
} catch (InterruptedException e) { //ignored }
}
退出while循环后,检查是否已通过另一个线程发出信号停止(stop = true
),如果是,则从run()
函数返回以允许线程自行清理。