mercredi 6 novembre 2019

missing or dropped loop cycles in android java switch statement

I have an infinite while loop as a test case for something I'm making and using switch case logic is showing repeatable and significant differences from if else logic. Essentially I am looping through, choosing a random number between the set of {0,1,2} and then waiting 1000 ms before selecting another number. The if statement logic works as expected (i.e. prints to the log every 1000 ms with some small microsecond drifts that are expected of a non RTOS). On the other hand, the switch statements seem to be what I'd describe as a best-effort system (i.e. the timing for each printed line is a multiple of 1000 ms, but several iterations just never print.). In other words I'd see my log output print something like

17:50:50:00: 1

17:50:51:00: 2

17:50:52:01: 3

17:50:53:01: 4

17:50:54:02: 5

for the if logic, but something like

17:50:50:00: 1

17:50:53:01: 4

17:50:54:02: 5

for the switch logic. I also noted a few other details that may be relevant:

  • There is no immediately obvious pattern to this (i.e. no missing interval every X time steps or something like this.)
  • I added a default case on the switch thinking I might be missing a case for whatever reason, but this did not appear to be the case (pun intended).

Is there any obvious reason for this? Does Java/Android give greater priority to if statement code and accept missing returns for switch statements or something along these lines? My problem is resolved simply by using the if statements in place of the switch statements, but I'm just curious as to why this is necessary? Or am I simply making some typo simple error in syntax that is causing this unexpected behavior in the switch statements?

This a bit of psudocode but it illustrates the sole changes that generate the differences I'm seeing (i.e. there is other code at play, but nothing changes but this). Below you'll see the switch case and if else logic:

public void run(){
    while(true){
        action = randomIntBetweenZeroAndTwo()
        Log.i('actions', String.valueOf(action));
        switch (action){
            case 0:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            case 1:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            case 2:
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            default:
                Log.i("distribution", "default case selected with action = " + action);
                }
    }
}
public void run(){
    while(true){
        action = randomIntBetweenZeroAndTwo()
        Log.i('actions', String.valueOf(action));
        if (action == 0){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        else if (action == 1){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        else {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

If it makes any differences here are various specs of my dev system:

PC OS: Ubuntu 18.04

Android OS: 5.1.1

Phone: Nexus 4

Android Studio 3.5.2

Aucun commentaire:

Enregistrer un commentaire