杀死Android/Java中的*无响应*线程 [英] Killing an *unresponsive* thread in Android/Java

查看:56
本文介绍了杀死Android/Java中的*无响应*线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道正常关闭线程所接受的正确解决方案.

I know the accepted, correct solutions for gracefully closing a thread.

但是假设我的游戏应该是容错的,并且在启动新游戏时,它会尝试优雅地关闭旧游戏的(已暂停)线程.如果它无法加入/关闭它(例如,由于旧线程有故障并且处于无限循环中),它将实例化新线程并启动它.但是我不喜欢旧线程仍然在那里消耗资源的事实.

But assume my game is supposed to be fault-tolerant, and when a new gamegplay is started, it tries to gracefully close the (now-paused) thread of the old gameplay. If it fails to join it / close it (e.g. because the old thread is buggy and is in an infinite loop), it instantiates the new Thread and starts it. But I don't like the fact that the old thread is still there, eating resources.

是否存在一种可以在不终止进程的情况下杀死无响应线程的方法?在我看来,实际上,我没有读到某个地方的线程也可能不会对Thread.stop()做出反应.

Is there an accepted way to kill an unresponsive thread without killing the process? It seems to me there isn't, in fact, I read somewhere that a Thread might not react to Thread.stop() either.

所以没有办法在无限循环中处理线程(例如由于错误)?即使它对Thread.stop()做出反应,文档也说Thread.stop()可能会使Dalvik VM处于不一致的状态...

So there is no way dealing with a thread in an infinite loop (e.g. due to a bug), is it? Even if it reacts to Thread.stop(), the docs say that Thread.stop() may leave Dalvik VM in an inconsistent state...

推荐答案

如果需要此功能,则必须设计并实现.显然,如果您没有设计和实现正常的方式关闭线程,则将无法正常关闭线程.没有通用的解决方案,因为该解决方案是针对特定应用程序的.例如,它取决于线程可能持有的资源以及线程可能持有的锁或已损坏的共享状态.

If you need this capability, you must design it and implement it. Obviously, if you don't design and implement a graceful way to shut down a thread, then there will be no way to gracefully shut down a thread. There is no generic solution because the solution is application-specific. For example, it depends on what resources the thread might hold and what shared state the thread may hold locks on or have corrupted.

典型答案是:如果您需要此功能,请不要使用线程.使用流程.

The canonical answer is this: If you need this capability, don't use threads. Use processes.

核心原因是线程的工作方式.您获取了一个锁,然后操作了共享数据.在处理该共享数据时,它可能会进入不一致状态.在释放锁之前,将数据恢复到一致状态是线程的绝对责任.(例如,考虑从双向链接列表中删除对象.必须先调整前向链接或反向链接.在这两个操作之间,链接列表处于不一致状态.)

The core reason is the way threads work. You acquire a lock and then you manipulate shared data. While you're manipulating that shared data, it can enter an inconsistent state. It is the absolute responsibility of a thread to restore the data to a consistent state before releasing the lock. (Consider, for example, deleting an object from a doubly-linked list. You must adjust the forward link or the reverse link first. In between those two operations, the linked-list is in an inconsistent state.)

说您有以下代码:

  1. 获取锁或输入同步块.

  1. Acquire a lock or enter a synchronized block.

开始修改锁保护的共享状态.

Begin modifying the shared state the lock protects.

Bug

将锁保护的数据恢复为一致状态.

Return the data the lock protects to a consistent state.

释放锁.

那么,现在,我们该怎么办?在第3步,线程持有一个锁,并且遇到错误并触发了异常.如果我们不释放在步骤1中获得的锁,那么每个试图获得相同锁的线程将永远等待,这注定要失败.如果我们确实释放了在第1步中获取的锁,那么每个获取该锁的线程都将看到不一致的共享状态,因为该线程从未执行过第4步,因此无法清除该线程.无论哪种方式,我们都注定要失败.

So, now, what do we do? At step 3, the thread holds a lock and it has encountered a bug and triggered an exception. If we don't release the lock it acquired in step 1, every thread that tries to acquire that same lock will wait forever, and we're doomed. If we do release the lock it acquired in step 1, every thread that acquires the lock will then see the inconsistent shared state the thread failed to clean up because it never got to step 4. Either way, we're doomed.

如果线程遇到异常情况,则应用程序程序员没有创建理智的处理方式,则该过程注定要失败.

If a thread encounters an exceptional condition the application programmer did not create a sane way to handle, the process is doomed.

这篇关于杀死Android/Java中的*无响应*线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆