Java 机器拒绝某些形式的循环代码

发布于 2024-12-08 20:54:25 字数 1538 浏览 1 评论 0原文

Java 机器似乎在某些类型的循环上失败,这些循环对于其系统检查来说似乎是无限的,但实际上是由循环类之外的代码终止的。这种情况并不经常发生,但在我最近的 TickleService 中发现得最明显,其中代码的有限循环运行没有问题,但需要任何外部终止的循环失败。例如:

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 中编写的所有服务似乎都没有出现该问题。有谁知道这是为什么?我很想更好地理解这个问题。

It would appear that the Java machine fails on certain types of loop that appear to be infinite to its system check but are in fact terminated by code outside the loop's class. This does not happen often, but it was most noticeably found in my recent TickleService, where finite loops of code ran without trouble but loops that required ANY outside termination failed. For example:

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

The above caused an immediate system ANR crash(CPU usage >99% exception).
However, the following version would run only once and cease further operation without ever crashing:

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

The above loop executed once and ceased to loop.
Next, if the code had a finite loop it would execute flawlessly:

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);
        }
    }
...
}

This above loop would run 5 times each one second apart as expected.
Ultimately, the fix I applied was to run the following in which I tried to trick the JVM into thinking that no looping was occurring at all:

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
 }
 ...
}

This trick executed without exception and reliably produced tickles one second apart.
Many tests were run, all confirmed that continuous loops failed if they terminated according to triggers outside the class, but ran correctly if terminated internally. Ultimately, while I strongly suspect either a purposeful design flaw or unintended bug in the Dalvik java machine causes this problem, but the evidence was only circumstantial. Furthermore, the problem does not seem to occur for all services that I have written in Android. Does anyone know why this is? I would love to understand this problem better.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

帅冕 2024-12-15 20:54:25

在您展示的所有情况下,Dalvik 虚拟机都运行正常。运行无限循环并因此阻塞主 UI 线程是不好的做法,只会导致 ANR 错误。我没有看到你的其他代码,所以我无法回复它。

The Dalvik Virtual Machine is running correctly in all cases you have shown. Running infinite loops and thus blocking the main UI thread is poor practice and will only get you ANR errors. I haven't seen your other code so I cannot respond to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文