我知道正确关闭线程的已接受的正确解决方案。
但是假设我的游戏应该是容错的,并且当一个新的游戏玩法开始时,它试图优雅地关闭旧游戏玩法的(现在暂停的)线程。如果它无法加入/关闭它(例如因为旧线程有问题而且处于无限循环中),它会实例化新线程并启动它。但我不喜欢旧线程仍在那里,吃资源的事实。
是否有一种可以接受的方法来杀死一个没有响应的线程而不会杀死进程?事实上,在我看来,我并没有读到Thread可能不会对Thread.stop()作出反应。
因此无法在无限循环中处理线程(例如由于错误),是吗?即使它对Thread.stop()作出反应,文档也说Thread.stop()可能使Dalvik VM处于不一致的状态......
答案 0 :(得分:1)
如果您需要此功能,则必须进行设计并实施。显然,如果你没有设计和实现一种优雅的方式来关闭一个线程,那么就没有办法优雅地关闭一个线程。没有通用解决方案,因为该解决方案是特定于应用程序的。例如,它取决于线程可能拥有的资源以及线程可能锁定或已损坏的共享状态。
规范的答案如下:如果您需要此功能,请不要使用线程。使用流程。
核心原因是线程的工作方式。您获得一个锁,然后您操纵共享数据。在操作共享数据时,它可能会进入不一致状态。在释放锁之前,将数据恢复到一致状态是线程的绝对责任。 (例如,考虑从双向链表中删除对象。必须首先调整前向链接或反向链接。在这两个操作之间,链表处于不一致状态。)
说你有这段代码:
获取锁定或输入同步块。
开始修改锁保护的共享状态。
错误
将锁保护的数据返回到一致状态。
解锁。
那么,现在,我们该怎么办?在第3步,线程持有一个锁,它遇到了一个错误并触发了一个异常。如果我们不释放它在步骤1中获取的锁,那么试图获取同一个锁的每个线程将永远等待,我们注定要失败。如果我们确实释放它在步骤1中获取的锁,那么获取锁的每个线程将会看到线程无法清理的不一致共享状态,因为它从未进入第4步。无论哪种方式,我们都注定失败。
如果一个线程遇到异常情况,那么应用程序员就没有创建一个理智的方法来处理,这个过程注定要失败。