Human
Human

Reputation: 565

Run code every second by using System.currentTimeMillis()

I am trying to run a line of code every second by using System.currentTimeMillis();.

The code:

     while(true){
           long var = System.currentTimeMillis() / 1000;
           double var2 = var %2;

           if(var2 == 1.0){

               //code to run

           }//If():

        }//While

The code which I want to run, runs multiple times because var2 is set to 1.0 multiple times due to the infinite whole loop. I just want to run the code line when var2 is first set to 1.0, and then every time again when var2 becomes 1.0 after 0.0.

Upvotes: 13

Views: 26395

Answers (5)

Peter Lawrey
Peter Lawrey

Reputation: 533890

If you want to busy wait for the seconds to change you can use the following.

long lastSec = 0;
while(true){
    long sec = System.currentTimeMillis() / 1000;
    if (sec != lastSec) {
       //code to run
       lastSec = sec;
    }//If():
}//While

A more efficient approach is to sleep until the next second.

while(true) {
    long millis = System.currentTimeMillis();
    //code to run
    Thread.sleep(1000 - millis % 1000);
}//While

An alternative is to use a ScheduledExecutorService

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();

ses.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        // code to run
    }
}, 0, 1, TimeUnit.SECONDS);

// when finished
ses.shutdown();

The advantage of this approach is that

  • you can have a number of tasks with different periods sharing the same thread.
  • you can have non-repeating delay or asynchronous tasks.
  • you can collect the results in another thread.
  • you can shutdown the thread pool with one command.

Upvotes: 24

Nick
Nick

Reputation: 1340

preferred way:

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

Then pass in Runnables like:

scheduler.scheduleWithFixedDelay(myRunnable, initDelay, delay, TimeUnit.MILLISECONDS);

I wouldn't use the Timer. Schedulers are built to handle problems that Timers can cause. Also, the Thread.sleep is good for a simple program that you're writing quickly for proof of concept type things but I wouldn't use it in the enterprise world.

Upvotes: 1

RNJ
RNJ

Reputation: 15572

I'd use the java executor libraries. You can create a ScheduledPool that takes a runnable and can run for any time period you want. For example

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new MyRunnable(), 0, 5, TimeUnit.SECONDS);

Will run the MyRunnable class every 5 seconds. MyRunnable must implement Runnable. The trouble with this is that it will (efficiently) create a new thread each time which may or may not be desirable.

Upvotes: 4

Juvanis
Juvanis

Reputation: 25950

Using Thread.sleep(); would be perfect for your case.

 while(true)
 {
    Thread.sleep(1000); // Waiting before run.
    // Actual work goes here.
 }

Upvotes: 2

KV Prajapati
KV Prajapati

Reputation: 94653

You should have to use java.util.Timer and java.util.TimerTask class.

Upvotes: 2

Related Questions