Run code every second by using System.currentTimeMillis() - java

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.

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.

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.

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

Using Thread.sleep(); would be perfect for your case.
while(true)
{
Thread.sleep(1000); // Waiting before run.
// Actual work goes here.
}

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.

Related

How will you refactor the following code?

while(!isRunning){
now = getSystemTime();
deltaTime = now - lastTime;
lastTime = now;
if(deltaTime >= 1000){
//do something
}
}
This piece of code looks awkward to me. I want the thread to "do something" every 1000 units of time, but the while loop will run infinitely before 1000 units of time passes, which wastes resoure of CPU. How do you think I could refactor this piece of pseudo code? Notice that it may be true that "do something" may take more than 1000 units of time.
PS:
I am coding using java and want a solution to the problem with Java.
Take a look at Java scheduled executors. There is a method called scheduleAtFixedRate you can use. There is a class called TimeUnit which is used in this method to make things run at certain periods. Disadvantage to this is you have to create a instanve of Callable or Runnable which is a bit clunky in my opinion
First, I would make a function just to keep track of time so the code looks cleaner. Second, if you put a sleep inside the while so we dont occupy CPU time with busy wait. You can have more timed sections with more timer variables.
int countTime(int & time){
now = getSystemTime();
deltaTime = now - time;
lastTime = now;
return deltaTime
}
...
while(!isRunning){
if(countTime(timer) >= 1000){
//do something
}
usleep(100000) // sleep so we don't occupy CPU
}
The problem here is that the code is performing a busy wait, meaning, wasting CPU cycles until delta is bigger than 1 second.
It would be better to simply sleep for a second instead, and allow other processes to take advantage of the CPU cycles while your process is doing nothing:
while(!isRunning){
doSomething();
sleep(1000); // see implementation below
}
...
void sleep(int milli) {
try {
Thread.sleep(milli);
} catch (InterruptedException e) {
// ignore
}
}
Is it going to run forever? What is the context?
Try to make it like this:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Runnable beeper = new Runnable() {
public void run() { algorithm something here! }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 1000, 1000, TimeUnit.MILLISECONDS);
Maybe it solve your problem!
If you have some question about the methods posted above, please check the oracle documentation:
https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html

Performing a task every x time

I'm trying to perform a task every 5 minute.
The task need to start from: xx:00, xx:05, xx:10, xx:15 and so on so if the time is xx:37 the task will start in xx:40.
I'm used the following code to do that:
Date d1 = new Date();
d1.setMinutes(d1.getMinutes() + 5 - d1.getMinutes()%5);
d1.setSeconds(0);
this.timer.schedule(new Send(), d1, TEN_MINUTES/2);
Send looks like that:
class Send extends TimerTask
{
public void run()
{
if(SomeCondition)
{
Timestamp ts1 = new Timestamp(new java.util.Date().getTime());
SendToDB(ts1);
}
}
}
So the result should be records that if you % the minutes the result would be 0.
But the records time I have is:
*05:35:00
*07:44:40
*07:54:40
*09:05:31
*09:50:00
As you can see the first task start perfectly but then something went wrong.
My guess is that the task calculateds the 5 minute jump after the previous task is finished so the task run time effects, but it's just a guess.
The time a task takes to execute will delay the schedule. From the docs for schedule:
If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well.
You will be better off using scheduleAtFixedRate.
Alternatively, you might try using a simple Thread with a loop to repeatedly perform the task. The last step in the loop can be to sleep the necessary time until you want to start the task again. Assuming that no one iteration of the loop takes five minutes, this will eliminate cumulative delays.
public void run() {
long start = System.currentTimeMillis();
while (shouldRun()) {
doTask();
long next = start + FIVE_MINUTES;
try {
Thread.sleep(next - System.currentTimeMillis());
start = next;
} catch (InterruptedException e) {
. . .
}
}
}
This will start each iteration at the next five-minute interval and will not accumulate delays due to the running time of doTask() or any system delays. I haven't looked at the sources, but I suspect that this is close to what's in Timer.scheduleAtFixedRate.
Why dont you use a Task scheduler or simply a sleep command in a loop which lets the thread sleep for 5 minutes then continue.
An alternative would be to use a Timer class
I would probably make use of ScheduleExecutorService.scheduleAtFixedRate which is a more modern approach than using a Timer and would allow for having multiple worker threads in case there are many tasks being scheduled.

(Java) Ticker that adds to counter variable

Im trying to get a timer to work in my current java project that adds 1 to an integer variable every n microseconds (e.g. 500 for 1/2 a second), within an infinite loop, so that it is always running while the program runs.
Heres the code i have currently:
public class Ticker
{
public int time = 0;
long t0, t1;
public void tick(int[] args)
{
for (int i = 2; i < 1; i++)
{
t0 = System.currentTimeMillis();
do
{
t1 = System.currentTimeMillis();
}
while (t1 - t0 < 500);
time = time + 1;
}
}
}
Everyone was so helpful with my last question, hopefully this one is just as easy
Here is an comparable ScheduledExecutorService example which will update the time variable with a 500 millisecond interval:
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
exec.scheduleAtFixedRate(new Runnable(){
private int time = 0;
#Override
public void run(){
time++;
System.out.println("Time: " + time);
}
}, 0, 500, TimeUnit.MILLISECONDS);
This approach is preferred over using Timer.
I think you want
Thread.sleep(500);
At the moment you're consuming CPU cycles waiting for 500ms (you mention microseconds but I believe you want milliseconds). The above puts your current thread to sleep for 500ms and your process won't consume any CPU (or minimal at least - garbage collection will still be running). If you watch the CPU when you run your version you should see the difference.
See here for more info.
If you need to do it in a different thread, take a look on Timer:
int delay = 500; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
time++
}
};
new Timer(delay, taskPerformer).start();
Note that the code above cannot utilize a local variable (they must be declared as final to access them in an anonymous class). It can be a member however.
What you have is rather inefficient, since it wastes CPU cycles waiting for the next wakeup time. If I were you, I'd rewrite the function using Thread.sleep().
As to why your current code doesn't work, your for loop conditions are off, so the loop is never entered.
To have the timer code run concurrently with whatever other logic you have in your program, you'll need to look into threading.
It sounds like you might want to look into multithreading. If you search SO for this, you will find several good question/answer threads. There are also tutorials elsewhere on the web...
Have a look at Timer or better ScheduledExecutorService. They enable you to execute some action periodically and handle the computations surrounding that.

Java - Android Programming - Loop Fail [duplicate]

I am using a while loop with a timer.
The thing is that the timer is not used in every loop.
It is used only the first time. After the first time the statements included inside the loop are executed without the delay that i have set.
How is this even possible since the timer is included inside the while loop.
Any solutions ?
int count = 1;
while (count <= 10) {
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
// Stuff the while loop executes
}
});
}
}, 20000);
count++;
}
The TimerTask kicks off a new Thread and then the loop proceeds as normal.
The execution of the thread does not cause a delay to the execution of the code in your loop.
It's because you're queueing up 10 toasts all to execute in one hour. Each iteration of your loop takes only a fraction of a millisecond or maybe a tad bit more than that. To enqueue them properly, you could do 3600000 * count instead of 3600000 each time.
This is a terrible way to do it though. You should use AlarmManager for stuff like this.
You're scheduling 10 TimerTasks to execute after an hour, at the same time. So all 10 tasks are being executed after 1 hour, which makes it seem like 1 execute since all the Toast messages display at the same time. To schedule tasks at a fixed delay, with the first task starting in 1 hour, use this method:
Timer t = new Timer();
t.schedule(task, 3600000, 3600000);
This will execute until you call t.cancel().

Java / Android Programming - Loop FAIL

I am using a while loop with a timer.
The thing is that the timer is not used in every loop.
It is used only the first time. After the first time the statements included inside the loop are executed without the delay that i have set.
How is this even possible since the timer is included inside the while loop.
Any solutions ?
int count = 1;
while (count <= 10) {
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
// Stuff the while loop executes
}
});
}
}, 20000);
count++;
}
The TimerTask kicks off a new Thread and then the loop proceeds as normal.
The execution of the thread does not cause a delay to the execution of the code in your loop.
It's because you're queueing up 10 toasts all to execute in one hour. Each iteration of your loop takes only a fraction of a millisecond or maybe a tad bit more than that. To enqueue them properly, you could do 3600000 * count instead of 3600000 each time.
This is a terrible way to do it though. You should use AlarmManager for stuff like this.
You're scheduling 10 TimerTasks to execute after an hour, at the same time. So all 10 tasks are being executed after 1 hour, which makes it seem like 1 execute since all the Toast messages display at the same time. To schedule tasks at a fixed delay, with the first task starting in 1 hour, use this method:
Timer t = new Timer();
t.schedule(task, 3600000, 3600000);
This will execute until you call t.cancel().

Categories