I want to make a simple program that counts seconds up until 100 using Java.Util.Timer
The code below is the code I am using, however it simply prints all the numbers out at once without waiting a second between each one. How would I fix that? (Ordinarily I would use a thread.sleep but this is just proof of concept.)
import java.util.Timer;
import java.util.TimerTask;
public class Main {
static Timer timer = new Timer();
static int seconds = 0;
public static void main(String[] agrs) {
MyTimer();
}
public static void MyTimer() {
TimerTask task;
task = new TimerTask() {
#Override
public void run() {
while (seconds < 100) {
System.out.println("Seconds = " + seconds);
seconds++;
}
}
};
timer.schedule(task, 0, 1000);
}
}}
Don't use this while loop:
task = new TimerTask() {
#Override
public void run() {
while (seconds < 100) {
System.out.println("Seconds = " + seconds);
seconds++;
}
}
};
The while loop will run immediately as there's no delay inside of it. Instead you want to Timer itself to be your loop, meaning there's no need for this loop.
Instead use an if block to check if the count is < some max number and if so, print it out and increment the count.
task = new TimerTask() {
private final int MAX_SECONDS = 100;
#Override
public void run() {
if (seconds < MAX_SECONDS) {
System.out.println("Seconds = " + seconds);
seconds++;
} else {
// stop the timer
cancel();
}
}
};
In order to stop the timer the timer.cancel() should be invoked (not only the one of the TimerTask), so the timer is stopped and in cascade the other related threads.
#Override
public void run() {
if (seconds < Orologio.MAX_SECONDS) {
System.out.println("Seconds = " + seconds);
seconds++;
} else {
timer.cancel();
System.out.println("Timer canceled");
}
}
};
Related
The variable totalTime doesn't change.
What can I do?
static volatile long totalTime = 0;
private void initTimer() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
totalTime += 1000;
}
}, 1000);
}
This code reproduces my problem:
public class Main {
public static volatile long totalTime = 0;
public static void main(String ... args){
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
totalTime +=1000;
}
}, 1000);
for (int i = 0; i<10; i++) {
System.out.println(totalTime);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getStackTrace();
}
}
}
}
Current output:
0
0
1000
1000
1000
1000
1000
1000
1000
1000
What I need to get this:
0
1000
2000
3000
...
Your fundamental problem is you are calling the wrong version of schedule.
time.schedule(timerTask, delay)
executes the task once after the specified delay.
You want this version:
time.schedule(timerTask, delay, period)
which executes the task after the specified delay, and repeatedly executes the task thereafter every period.
Also, to get the output you want, you need to make sure the timings of the waking of the main thread and the timer thread are not too close, so you should offset them by initially sleeping half the period.
Try this:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
totalTime += 1000;
}
}, 1000, 1000);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.getStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println(totalTime);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getStackTrace();
}
}
So I click a start button and every second I change the text of a label with counting the time:
new CountDownTimer(30000, 500) {
public void onTick(long millisUntilFinished) {
if (zaciatokgotten) {
T2 = new Timer();
tt2 = new TimerTask() {
public void run() {
if(stopclicked == true) {
this.cancel();
}
handler.post(new Runnable() {
public void run() {
hasStartedtt2 = true;
calendar = Calendar.getInstance();
simpledate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
do_casu = simpledate.format(calendar.getTime());
zaciatok_hour = zaciatok.substring(11, 13);
zaciatok_minute = zaciatok.substring(14, 16);
koniec_hour = do_casu.substring(11, 13);
koniec_minute = do_casu.substring(14, 16);
zaciatok_sekundy = zaciatok.substring(17, 19);
koniec_sekundy = do_casu.substring(17, 19);
final_hour = ((Integer.parseInt(koniec_hour) - Integer.parseInt(zaciatok_hour)) );
final_minute = Integer.parseInt(koniec_minute) - Integer.parseInt(zaciatok_minute);
final_seconds = Integer.parseInt(koniec_sekundy) - Integer.parseInt(zaciatok_sekundy) - 1;
if (final_seconds < 0) {
final_seconds = final_seconds + 60;
final_minute = final_minute - 1;
}
if (final_minute < 0) {
final_hour = final_hour - 1;
final_minute = final_minute + 60;
}
if (final_hour < 0) {
final_hour = 0;
}
if (final_minute < 0) {
final_minute = 0;
}
if (final_hour == 0) {
if (final_minute == 0) {
txtProgress.setText(final_seconds + " s");
} else {
txtProgress.setText(final_minute + " m " + final_seconds + " s");
}
} else {
txtProgress.setText(final_hour + " h " + final_minute + " m " + final_seconds + " s");
}
}
});
}
};
T2.schedule(tt2, 1000, 1000);
if(once ==0) {
new Thread(new Runnable() {
#Override
public void run() {
while (pStatus <= 100) {
handler.post(new Runnable() {
#Override
public void run() {
progressBar.setProgress(pStatus);
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
pStatus++;
if (pStatus == 100) {
pStatus = 0;
}
}
}
}).start();
once++;
this.cancel();
}
}}
public void onFinish() {
}
}.start();
After I click the stop button the progressBar stops spinning, which is correct, but the time keeps incrementing, what am I doing wrong? Note that this issue is not present on the phones I used to test it, but its present on tablet devices, maybe they handle threads differently?
The code for stopping the timer here:
stopclicked = true
if(hasStartedtt2 == true) {
tt2.cancel();
// handler.removeCallbacksAndMessages(null);
}
if (T2 != null) {
T2.cancel();
T2.purge();
}
pStatus = 101;
EDIT1: I just noticed it is stopped, but only 20 - 25 seconds after I clicked Stop, whats causing the delay?
The reason time won't stop (or stops "only 20 - 25 seconds after you clicked Stop") is the new instances of T2 = new Timer() and tt2 = new TimerTask() you create on every CountDownTimer's onTick(). The old instances of Timer and TimerTask keep residing on Java heap making their job until getting garbage-collected. You may notice the time changes being bumpy.
Moreover, you seem to overcomplicate the task implementation. You might not need neither Timer nor TimerTask. The following example, that stops the time going, uses only CountDownTimer without Timer and TimerTask. I simplified the code a bit for the sake of brevity.
private CountDownTimer timer;
private TextView txtProgress;
private Button stopButton;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtProgress = findViewById(R.id.tv);
timer = new CountDownTimer(30000, 500) {
public void onTick(long millisUntilFinished) {
handler.post(() -> {
txtProgress.setText("any text");
});
}
public void onFinish() { }
}.start();
findViewById(R.id.stopButton).setOnClickListener(v -> timer.cancel());
}
I have a class countdown timer that I want to reset but when it resets it wont start again.
Basicaly when the counter gets to 0 (when the status is "done"), sets x = 1 and then in the activity checks if x = 1 , and then the counter resets. When the reset method from within the class is called it shows that it has reset but it wont start counting again
Timer class:
public class countdown_timer {
private long pls;
private long millisInFuture;
private long countDownInterval;
private boolean status;
int x = 0;
public countdown_timer(long pMillisInFuture, long pCountDownInterval) {
this.millisInFuture = pMillisInFuture;
this.countDownInterval = pCountDownInterval;
this.pls = pMillisInFuture;
status = false;
Initialize();
}
public void Stop() {
status = false;
}
public int GetNumberX() {
return x;
}
public void Reset() {
millisInFuture = pls;
x=0;
}
public void Start() {
status = true;
}
public void Initialize() {
final Handler handler = new Handler();
Log.v("status", "starting");
final Runnable counter = new Runnable() {
public void run() {
long sec = millisInFuture / 1000;
if (status) {
if (millisInFuture <= 0) {
Log.v("status", "done");
x = 1;
} else {
Log.v("status", Long.toString(sec) + " seconds remain");
millisInFuture -= countDownInterval;
handler.postDelayed(this, countDownInterval);
}
} else {
Log.v("status", Long.toString(sec) + " seconds remain and timer has stopped!");
handler.postDelayed(this, countDownInterval);
}
}
};
handler.postDelayed(counter, countDownInterval);
}
Activity that uses the timer class:
mycounterup = new countdown_timer(startcard, 1000);
xup = mycounterup.GetNumberX();
if (xup == 1) {
mycounterup.Reset();
mycounterup.Start();
Thanks for any help.
try changing your start method as and one thing more i don't know if its a typo or what change mycounter.Start(); to mycounterup.Start();
public void Start() {
status = true;
Initialize();
}
save the counter state so that next time if you have to pause or resume the thing you are able to do it also
You should change your Reset method:
public void Reset() {
millisInFuture = pls;
x=0;
Initialize();
}
I want to use TimerTask for Sleep, but I am unable to run this code.
The run function is called for the first time, and then it waits infinitely. Is there any issue with my code?
import java.util.Timer;
import java.util.TimerTask;
public class TimeExecutor {
class LocalSleep extends TimerTask {
private int noOfSeconds;
private int count = 0;
private Timer timer;
public LocalSleep(int noOfSeconds, Timer timer) {
this.noOfSeconds = noOfSeconds;
this.timer = timer;
}
void sleeeep() {
if (count < noOfSeconds) {
System.out.println("Count: " + count);
count++;
} else
timer.cancel();
}
#Override
public void run() {
sleeeep();
}
}
public static void main(String args[]) {
Timer timer = new Timer();
TimeExecutor t = new TimeExecutor();
timer.schedule(t.new LocalSleep(5, timer), 1000);
}
}
Working after replacing
timer.schedule(t.new LocalSleep(5, timer), 1000);
with:
timer.schedule(t.new LocalSleep(5, timer), 0, 1000);
I can't seem to get this timer to go off. the program compiles and from my understanding this should ping every 1000ms or 1 second and perform the lines in the actionPerformed{} function.
public void stringGeneration(String args[]){
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String fullIstring = java.lang.String.valueOf(injectString[0] + injectString[1] + injectString[2] + injectString[3] + injectString[4]);
jLabel3.setText(fullIstring);
System.out.println("output");
}
};
Timer timer = new Timer(1000, taskPerformer);
timer.setRepeats(true);
timer.start();
//Thread.sleep(500);
}
i just gave you an example and not something to copy paste. But you can try this if you want to try as is. In your case the above example should look like:
class HeartBeatTask extends TimerTask {
private int timerInterval;
public HeartBeatTask(int timeInterval)
{
this.timerInterval = timeInterval;
}
public void run()
{
String fullIstring = java.lang.String.valueOf(injectString[0] + injectString[1] + injectString[2] + injectString[3] + injectString[4]);
jLabel3.setText(fullIstring);
System.out.println("output");
}
}
Your method will then call the above class like this:
public void stringGeneration(String args[]){
HeartBeatTask tt = new HeartBeatTask();
t1.schedule(tt, 0, 1000 * 60 * 2);
}
This is how i would to a scheduled task in java:
import java.util.TimerTask;
class HeartBeatTask extends TimerTask
{
private int timerInterval;
public HeartBeatTask(int timeInterval)
{
this.timerInterval = timeInterval;
}
public void run()
{
// Your function call to schedule here
}
public static void main(String[] args)
{
java.util.Timer t1 = new java.util.Timer();
HeartBeatTask tt = new HeartBeatTask();
t1.schedule(tt, 0, 1000 * 60 * 2);
}
}
Hope that helps