2012-03-21 112 views
7

我有一个应用程序,当一个“游戏”统计时,它启动了几个不同的线程。我开始线程像这样:多线程的好习惯

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"; 
+0

获取堆栈跟踪相当昂贵,因此如果在创建线程并将其设置为“处理(线程[]线程)'时保存'线程[]''会更有效。是否有其他线程在游戏结束时继续运行,或者是为了防止您终止UI线程? – zapl 2012-03-21 01:51:04

+0

当“游戏”结束时,“活动”未完成,它会转到其他位置。 – John 2012-03-21 01:56:35

回答

4

你有正确的想法,但也有一些改进的方面:

  1. 不是查询系统为所有正在运行的线程,只是增加你的线程列表,只要你创建它们的。然后,您可以终止您创建的所有线程或等待其完成(加入)。
  2. 中断只会中断处于阻塞状态的线程,因此您需要有一个线程定期检查的额外标志(即在每个“工作周期”之后)。
  3. 捕捉线程中的中断异常并处理它(即正常退出)。
+0

+1谢谢!我最终把我的所有线程放入一个列表中,然后在游戏完成后将其杀死。 – John 2012-03-21 19:45:48

3

这不是一定一个坏的解决方案,但也有一些问题:

  • 如果你的线程是那种工作线程处理一个任务的完成,有可能是线程自行结束的更好的设计。换句话说,可能有更好的执行流程,最终不需要被杀。

  • 当你说“对所有正在运行的线程进行排序......”时,我想你正在查看JVM中所有正在运行的线程?如在沿着this SO question的行的东西?如果是这样的话,为什么不只是保留游戏拥有的所有线索的引用,然后专门杀死它们?而不是只寻找“killMeAtEnd”;我想不出你的策略会出现什么问题,但是跟踪你的线索似乎有点干净。

保持线程清洁绝对是一种好的做法。如果你的线程正在做一些没有特定任务的事情(例如等待网络io或其他东西),那么我的第一个建议有点不相关。我只是建议对于如何保持线程清洁的设计非常小心,因为线程错误可能是一个很大的麻烦。

+0

+1感谢您的帮助! – John 2012-03-21 19:46:36

0

ExecutorService类已经存在来处理这类问题。

为ExecutorService创建所有线程任务。

当游戏结束时,使用shutdownNow关闭ExecutorService。这会中断ExecutorService中的所有线程。然后,您可以在开始新游戏时创建一个新的ExecutorService。

如果线程数量是固定的,您可以使用Executors.newFixedThreadPool()来创建ExecutorService。

如果线程数是可变的,那么可以使用Executors.newCachedThreadPool创建ExecutorService。