这是我的问题:我有一个对话框,其中包含一些用户可以更改的参数(例如通过微调器).每次更改其中一个参数时,我都会根据新参数值启动一个线程来更新3D视图.如果用户在第一个线程工作时更改了另一个值(或者通过在微调器箭头上单击多次再次返回相同的值),我想中止第一个线程(以及更新3D视图)并启动一个新线程使用最新的参数值.
我怎么能这样做?
PS:run()
我的线程方法中没有循环,因此检查标志不是一个选项:更新3D视图的线程基本上只调用一个执行时间很长的方法.我无法在此方法中添加任何标志,要求中止,因为我无法访问其代码.
尝试使用interrupt(),因为有些人已经说过,看看它是否会对你的线程产生任何影响.如果没有,请尝试销毁或关闭将使线程停止的资源.这有可能比尝试抛出Thread.stop()更好一点.
如果性能是可以容忍的,您可以将每个3D更新视为一个离散的不可中断事件,并让它一直运行到结束,然后检查是否有新的最新更新要执行.这可能会使GUI对用户有点不稳定,因为他们可以进行五次更改,然后查看事物前五次更改的图形结果,然后查看最新更改的结果.但是根据这个过程的持续时间,它可能是可以容忍的,并且它可以避免必须杀死线程.设计可能如下所示:
boolean stopFlag = false; Object[] latestArgs = null; public void run() { while (!stopFlag) { if (latestArgs != null) { Object[] args = latestArgs; latestArgs = null; perform3dUpdate(args); } else { Thread.sleep(500); } } } public void endThread() { stopFlag = true; } public void updateSettings(Object[] args) { latestArgs = args; }
正在更新3D视图的线程应该定期检查一些标志(使用a volatile boolean
)以查看它是否应该终止.如果要中止线程,只需设置标志即可.当线程接下来检查该标志时,它应该简单地断开用于更新视图并从其run
方法返回的任何循环.
如果你真的无法访问Thread正在运行的代码来检查一个标志,那么就没有安全的方法来停止Thread.在您的应用程序完成之前,此Thread是否会正常终止?如果是这样,是什么导致它停止?
如果它运行了很长一段时间,你只需要结束它,你可以考虑使用不推荐使用的Thread.stop()
方法.但是,它有一个很好的理由被弃用了.如果该线程在某些操作过程中停止,导致处于不一致状态或某些资源未正确清理,那么您可能遇到麻烦.这是文档中的注释:
这种方法本质上是不安全的.使用Thread.stop停止一个线程会导致它解锁它已锁定的所有监视器(这是未经检查的ThreadDeath异常向上传播的自然结果).如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为.stop的许多用法应该由代码修改,该代码只是修改某个变量以指示目标线程应该停止运行.目标线程应该定期检查此变量,并且如果变量指示它将停止运行,则以有序的方式从其run方法返回.如果目标线程等待很长时间(例如,在条件变量上),应该使用中断方法来中断等待.有关更多信息,请参阅为什么Thread.stop,Thread.suspend和Thread.resume已弃用?