多线程的好习惯
我有一个应用程序,当一个“游戏”统计时,它启动了几个不同的线程。我开始线程像这样:多线程的好习惯
Thread thread = new Thread(new Runnable()
{
public void run()
{
//...
}
});
thread.setName("killMeAtEnd");
thread.start();
当游戏结束时,我有游戏内一个dispose()方法,整理着所有正在运行的线程,结束全部有名为“killMeAtEnd”的主线之后。我的问题是,这是一个好的做法吗?我的目的是保持我的应用程序运行快速和杂乱无章,以我的经验来看,留下“悬挂”的线程往往会拖慢手机,直到应用程序终止。有一个更好的方法吗?这是否值得打扰?
编辑:
这是我dispose()
如果有人有兴趣。此代码在类游戏中。
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";
你有正确的想法,但也有一些改进的方面:
- 不是查询系统为所有正在运行的线程,只是增加你的线程列表,只要你创建它们的。然后,您可以终止您创建的所有线程或等待其完成(加入)。
- 中断只会中断处于阻塞状态的线程,因此您需要有一个线程定期检查的额外标志(即在每个“工作周期”之后)。
- 捕捉线程中的中断异常并处理它(即正常退出)。
+1谢谢!我最终把我的所有线程放入一个列表中,然后在游戏完成后将其杀死。 – John 2012-03-21 19:45:48
这不是一定一个坏的解决方案,但也有一些问题:
如果你的线程是那种工作线程处理一个任务的完成,有可能是线程自行结束的更好的设计。换句话说,可能有更好的执行流程,最终不需要被杀。
当你说“对所有正在运行的线程进行排序......”时,我想你正在查看JVM中所有正在运行的线程?如在沿着this SO question的行的东西?如果是这样的话,为什么不只是保留游戏拥有的所有线索的引用,然后专门杀死它们?而不是只寻找“killMeAtEnd”;我想不出你的策略会出现什么问题,但是跟踪你的线索似乎有点干净。
保持线程清洁绝对是一种好的做法。如果你的线程正在做一些没有特定任务的事情(例如等待网络io或其他东西),那么我的第一个建议有点不相关。我只是建议对于如何保持线程清洁的设计非常小心,因为线程错误可能是一个很大的麻烦。
+1感谢您的帮助! – John 2012-03-21 19:46:36
ExecutorService类已经存在来处理这类问题。
为ExecutorService创建所有线程任务。
当游戏结束时,使用shutdownNow关闭ExecutorService。这会中断ExecutorService中的所有线程。然后,您可以在开始新游戏时创建一个新的ExecutorService。
如果线程数量是固定的,您可以使用Executors.newFixedThreadPool()来创建ExecutorService。
如果线程数是可变的,那么可以使用Executors.newCachedThreadPool创建ExecutorService。
获取堆栈跟踪相当昂贵,因此如果在创建线程并将其设置为“处理(线程[]线程)'时保存'线程[]''会更有效。是否有其他线程在游戏结束时继续运行,或者是为了防止您终止UI线程? – zapl 2012-03-21 01:51:04
当“游戏”结束时,“活动”未完成,它会转到其他位置。 – John 2012-03-21 01:56:35