简体   繁体   中英

How to force a while loop execute one runnable at a time.

I am trying to make a simple timer with uneven time intervals after each repetition.

I start as follows:

            case R.id.start:
                timerRuns = true;
                startCycle();
                break;

The cycle itself looks like this:

private void startCycle() {
        pomodoroLeft = numPomodoro;
        while(pomodoroLeft > 0) {
            pomodoroLeft--;
            actualSeconds = pomodoroLength * ONE_MINUTE;
            setTimeAndRun(actualSeconds);
            actualSeconds = shortLength * ONE_MINUTE;
            setTimeAndRun(actualSeconds);


        }
    }

Method call:

 private void setTimeAndRun(long timePeriod) {
        runTime = timePeriod;
        runnable.run();
    }

And finally runnable itself:

private Runnable runnable = new Runnable()
    {

        public void run() {

            if (timerRuns) {
                runTime -= ONE_SECOND;
                String str = String.format("%1$02d : %2$02d",
                        TimeUnit.MILLISECONDS.toMinutes(runTime),
                        TimeUnit.MILLISECONDS.toSeconds(runTime) -
                                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(runTime))
                );
                timeShown.setText(str);

                mHandler.postDelayed(this, 1000);
                if(timeShown.getText().toString().contentEquals("00 : 00")) {
                    stopClock();
                    //here goes the alarm.
                }
            }

        }
    };

My problem is that when I start the timer while loop seems to execute everything despite incompliete run() of the previous method call. As a consequence timeShown TextView displays this actualSeconds = shortLength * ONE_MINUTE right away and skips 1 second each second because 2 runnables are running at the same time.

I want to achieve sequential execution here. What would be the best way to do so? Maybe implementing non-anonymous subclass and instantiate it every time would help?

Also, if you have any other suggestions that would improve my code I would greatly appreciate.

You should take a look at queues.

Here is a link to a similar question:

How to implement a queue of runnables

You should use the Executors.newSingleThreadExecutor()

http://developer.android.com/reference/java/util/concurrent/Executors.html#newSingleThreadExecutor%28java.util.concurrent.ThreadFactory

And here is a tutorial about the Executor:

http://tutorials.jenkov.com/java-util-concurrent/executorservice.html

here is also something that may help you understanding better multithreading in java:

Understanding multi-threading

hope this helps somehow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM