我有一个应用程序,当一个"游戏"统计数据,它启动了几个不同的线程。我开始这样的线程:
Thread thread = new Thread(new Runnable()
{
public void run()
{
//...
}
});
thread.setName("killMeAtEnd");
thread.start();
稍后当游戏结束时,我在游戏内部有一个dispose()方法,该方法对所有正在运行的线程进行排序,并结束所有具有名称" killMeAtEnd"的线程。我的问题是,这是一个好习惯吗?我的目的是保持我的应用程序快速运行和杂乱无章,根据我的经验,留下的线程"悬挂"在应用程序终止之前,往往会放慢手机的速度。有一个更好的方法吗?这甚至值得打扰吗?
修改
如果有人有兴趣,这是我的dispose()
。此代码属于Game类。
public void dispose()
{
Thread threads[] = (Thread[])Thread.getAllStackTraces().keySet().toArray();
for(int x=0;x<threads.length;x++)
{
Thread thread = threads[x];
if(thread.getName().equalsIgnoreCase(KILL))
{
try
{
thread.interrupt();
}catch(Exception e){Log.e(Viewer.GAME,Log.getStackTraceString(e));}
thread = null;
}
}
}
public static final String KILL = "endOnDispose";
答案 0 :(得分:4)
你有正确的想法,但有一些方面需要改进:
答案 1 :(得分:3)
这不是必然一个糟糕的解决方案,但存在一些问题:
如果你的线程是处理一个任务完成的排序的工作线程,那么线程可能会有更好的设计结束。换句话说,可能有更好的执行流程,不需要在最后被杀死。
当你说“对所有正在运行的线程进行排序......”时,我想你正在查看JVM中所有正在运行的线程?就像this SO question中的某些内容一样?如果是这种情况,为什么不只是保留对游戏所拥有的所有线程的引用,然后专门杀死它们?而不只是寻找“killMeAtEnd”;我无法想到你的策略会出现什么问题,但跟踪你的线程似乎更清晰。
保持线程清洁绝对是一种好习惯。如果你的线程正在做一些不那么具体的任务导向(例如,等待网络io,或者某些东西),那么我的第一个建议就有点无关紧要了。我建议你仔细考虑如何保持线程干净,因为线程错误可能会很大。
答案 2 :(得分:0)
已经存在类ExecutorService来处理这类问题。
为ExecutorService创建所有线程任务。
当游戏结束时,使用shutdownNow关闭ExecutorService。这将中断ExecutorService中所有线程的中断。然后,您可以在开始新游戏时创建新的ExecutorService。
如果修复了线程数,可以使用Executors.newFixedThreadPool()创建ExecutorService。
如果线程数是可变的,您可以使用Executors.newCachedThreadPool来创建ExecutorService。