Delay execution of code in method Java

18,244

Solution 1

Option 1: Using threads, you might run your job off the main (UI) thread:

new Thread(new Runnable() {
  // some code here ...

  // This might be in a loop.
  try {
    Thread.sleep(2000);
  } catch(InterruptedException ex) {
    // Handle ...
  }
 }
}).start();

Then, if this new thread you'd like to modify UI (i.e. show/hide button, display something on the screen etc), remember to pass that through the UI thread, as only this one can modify the UI. You might consider using Activity.runOnUiThread() for that.

Option 2: Another, more Android-style way of approaching that issue is to use AsyncTask. It contains three callbacks which can be used to do work on- and off- the UI thread. Sketch of such a code could look like:

 private class MyTask extends AsyncTask<Void, Void, Void> {
   protected Void doInBackground(Void... param) {
     // This method is running off the UI thread.
     // Safe to stop execution here.

     return null;
   }

   protected void onProgressUpdate(Void... progress) {
     // This methid is running on the UI thread. 
     // Do not stop thread here, but safe to modify the UI.
   }

   protected void onPostExecute(Long result) {
     // Also on UI thread, executed once doInBackground()
     // finishes.
   }
 }

Option 3: Then there is also a Timer, as suggested by @Stultuske. It's less flexible then AsyncTask, but handles the interval for you.

Solution 2

private Timer timer;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                //Generate number
            }
        }, 2000, 2000);

//Documentation (From SDK)
/**
             * Schedule a task for repeated fixed-rate execution after a specific delay
             * has passed.
             *
             * @param task
             *            the task to schedule.
             * @param delay
             *            amount of time in milliseconds before first execution.
             * @param period
             *            amount of time in milliseconds between subsequent    executions.
    public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
                if (delay < 0 || period <= 0) {
                    throw new IllegalArgumentException();
                }
                scheduleImpl(task, delay, period, true);
    }

and when you want to stop it

timer.cancel()

Solution 3

Depending on your needs, you can still accomplish what you seek with Handler.

You don't have to create/start the Handler in a while loop(which, as you noticed, just stacks up unless you stop the loop itself, but it is a nonsense).

Just create the Handler and tell him to post delayed your Runnable instance. In the Runnable at the very end you check your conditions. If it is still OK, then post another runnable delayed, else you do nothing and the Handler will have no more executions.

final Handler handler = new Handler();
Runnable runnable = new Runnable() {

    @Override
    public void run() {
        System.out.println("After 2 secs");
        random_number = Math.random();

        if (!stop) // should not be stopped, so we add another runnable;
        {
          handler.postDelayed(this, 2000);
        }
   }

handler.postDelayed(runnable, 2000);

The only downside is that Handler could freeze if the device is not used for a while, meaning it will start the counting back from where it left once the device screen is turned on.

It could do like 1 minute of correct work, then block at 1.4 seconds when the device is gone in sleep mode, and once it is turned on again, Handler would do the remaining 0.6 seconds.

Still, not knowing your needs you may be unaffected by this behavior and the answer may fit you.

Solution 4

if you want to use thread, do it like this :

Thread t = new Thread(){
    public void run(){
      while(true){
         if(stop) break;
         random_number = Math.random();
         sleep(2000);
      }
    }
};
t.start();
Share:
18,244
Confuse
Author by

Confuse

Updated on July 10, 2022

Comments

  • Confuse
    Confuse almost 2 years

    I want to generate random number after every 2 seconds in my java (Android) program continuously for at least 10 minutes. But I just want to pause/delay execution of code in only one method and not the whole program.

    I tried using Thread like this -

    boolean stop = false;
    int random_number = 0;
    
    while(true){
        if(stop){  //if stop becomes true, then
            return;  //terminate the method
        }
    
        random_number = Math.random(); //generate random number
                                       //which is used bu some other
                                       //part of code
        try {
            Thread.sleep(2000);        //delay the code for 2 secs
        } catch(InterruptedException ex) {  //and handle the exceptions
            Thread.currentThread().interrupt();
        }
    }
    

    However, this doesn't work as Thread.sleep stop the whole program execution instead on just stopping execution of code inside method and my whole screen becomes blank.

    I also tried using Handler but it didn't work either as it doesn't stop execution of code in my method and instead just stack up.

    This will demonstrate the working of it better -

    while(true){
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                System.out.println("After 2 secs"); //this gets printed
                                                   //later
            }
        }, 2000);
        System.out.println("Before 2 secs"); //this gets printed first
    }
    

    So the code stacks up making it equivalent to using while loop and make it incredibly slow.

    Also, since I'm developing app for Android, I'm running on Java SE 6, so I can't use scheduleAtFixedRate. Is there any other way in which I can accomplish this?

    Thanks a lot!

  • IAmGroot
    IAmGroot over 9 years
    what is stop . Plus should you not stop the while loop, rather than keep breaking for eternity.
  • Randyka Yudhistira
    Randyka Yudhistira over 9 years
    variable. it has boolean atribut. look at the question
  • IAmGroot
    IAmGroot over 9 years
    Ah yes, missed that. It should definately be while(!stop). the rest is wasted lines. You've also changed his return - the desire to stop the thread, into break which would just keep it looping idly.
  • Confuse
    Confuse over 9 years
    Thanks a lot for the answer