2011-10-10 72 views
2

似乎Java机器在某些类型的循环上失败,这些循环似乎对其系统检查是无限的,但实际上是由循环类以外的代码终止的。这种情况不常发生,但最近我在最近的TickleService中发现了这种情况,在这种情况下代码的有限循环无故障运行,但需要任何外部终止的循环失败。例如:Java机器拒绝某些形式的循环代码

class TickleService extends Service{ 
... 
    void execute(){ 
     while(true){ 
      Log.e("Test","Tickle"); 
      wait(1000); 
     } 
    } 
... 
} 

上述情况导致系统ANR立即崩溃(CPU使用率> 99%例外)。 但是,下面的版本将只运行一次,并停止进一步的操作而没有崩溃:

public class TickleService extends Service{ 
... 
    public static boolean amNotAlive = false; 
    void execute(){ 
     while(true){ 
      Log.e("Test","Tickle"); 
      if(amNotAlive) 
      break; 
      wait(1000); 
     } 
    } 
... 
} 

执行一次以上循环和停止循环。 接着,如果代码有一个有限环它将完美执行:

public class TickleService extends Service{ 
... 
    public static boolean amNotAlive = false; 
    void execute(){ 
     for(int i = 0; i<5;i++){ 
      Log.e("Test","Tickle"); 
      wait(1000); 
     } 
    } 
... 
} 

这上面的循环将运行5次,每次相隔一秒如预期。 最终,我修补程序应用是要运行中,我试图将JVM欺骗以为无循环在所有存在的以下内容:

public class TickleService extends Service{ 
... 
public static boolean amAlive = true; 
void execute(){ 
    Log.e("Test","Tickle"); 
    wait(1000); 
    if(amAlive) 
     restartService(); //pseudo code for doing startService on self 
} 
... 
} 

这招无一例外产生执行且可靠地发痒相隔一秒。 运行了许多测试,都证实如果连续循环根据类之外的触发器终止,则连续循环失败,但如果内部终止,则会正确运行。最终,尽管我强烈怀疑Dalvik java机器中有目的的设计缺陷或意外错误导致了这个问题,但证据只是间接的。此外,我在Android中编写的所有服务似乎都没有出现这个问题。有人知道为什么吗?我很想更好地理解这个问题。

+0

我认为你的修复最终会导致堆栈溢出 - 不知道“startService”是如何工作的(android没有经验)。 –

回答

3

Dalvik虚拟机在您显示的所有情况下都能正确运行。运行无限循环,从而阻塞主UI线程是不好的做法,只会让你的ANR错误。我还没有看到你的其他代码,所以我无法回应。

+0

这正是我需要知道的。我认为每个服务都在自己的线程上运行,但是如果它们全都在UI线程上运行,那么它就会探测到我所拥有的错误。谢谢! –