I have this code, which basically provides a custom timer for my application.
import java.util.Timer;
import java.util.TimerTask;
import org.apache.log4j.Logger;
public class SMSFirewallTimer {
private static Logger logger = Logger.getLogger(SMSFirewallTimer.class);
Timer timer;
String timerId;
public SMSFirewallTimer(int seconds, String string) {
timer = new Timer();
timerId = string;
logger.debug("SMSFirewallTimer: timer started for: "+seconds +"seconds");
timer.schedule(new Timeout(string), seconds*1000);
}
public void cancelTimer()
{
this.timer.cancel();
logger.debug("SMSFirewallTimer: Cancelling timer for : " + this.timerId);
}
class Timeout extends TimerTask {
private String string;
public Timeout(String string) {
this.string = string;
}
#Override
public void run() {
logger.debug("SMSFirewallTimer: Time's up! for: " + this.string );
timer.cancel(); //Terminate the timer thread
}
}
}
Now the problem arises that I want a isRunning() method in SMSFirewallTimer which will tell me that if the timer is still running or not, and it should also keep timeout in mind.
If I just declare a boolean as isTimer in this class it only holds good if we use cancelTimer(), but it wont come to know if timer expired, as its another scheduled method new Timeout(string).
Timeout is an inner class of SMSFirewallTimer which means that each instance of SMSFirewallTimer is tied to a specific instance of SMSFirewallTimer and that is has access to its fields and methods.
It should be sufficient to replace:
timer.cancel(); //Terminate the timer thread
with
cancelTimer(); //Terminate the timer thread
in the run method of Timeout.
Try this
import java.util.Timer;
import java.util.TimerTask;
import org.apache.log4j.Logger;
public class SMSFirewallTimer {
private static Logger logger = Logger.getLogger(SMSFirewallTimer.class);
Timer timer;
String timerId;
private Boolean isRunning;
public SMSFirewallTimer(int seconds, String string) {
timer = new Timer();
timerId = string;
logger.debug("SMSFirewallTimer: timer started for: "+seconds +"seconds");
isRunning = true;
timer.schedule(new Timeout(string), seconds*1000);
}
public void cancelTimer()
{
isRunning = false;
this.timer.cancel();
logger.debug("SMSFirewallTimer: Cancelling timer for : " + this.timerId);
}
public boolean isRunning() {
return isRunning;
}
class Timeout extends TimerTask {
private String string;
public Timeout(String string) {
this.string = string;
}
#Override
public void run() {
logger.debug("SMSFirewallTimer: Time's up! for: " + this.string );
isRunning = false;
timer.cancel(); //Terminate the timer thread
}
}
}
Also you can keep reference for Timeout if you don't want to have access from your Timeout to your SMSFirewallTimer isRunning field.
Related
I am trying to call the "checkTime" method of the "Timer" class from outside this class but that is not working... is this the right way ? how can I fix this? I am using threads
class Timer implements Runnable{
private boolean running;
private int time = 0;
public Timer(){
time = 10;
running = false;
}
public boolean isRunning(){
return running;
}
public void checkTime(){
if(isRunning()){
System.out.println("Timer is at: "+ time/1000 + " seconds");
}
}
#Override
public void run() {
try {
running = true;
Thread.sleep(1000L);
}
running = false;
}
}
}
In the other class i have something like this
Thread timer;
timer = new Thread(new Timer());
//check timer
if(cooking){
timer.checkTime();
} else{
System.out.println("The timer is set to: " + timer + " seconds");
}
break;```
Make a variable of the Timer object before you instantiate a the Thread object.
Example:
Timer timer = new Timer();
Thread thread = new Thread(timer);
// get the checkTime() value here
System.out.println(timer.checkTime());
You really need to watch out for concurrency issues as you have multiple threads managing the same variables (int time and boolean running).
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;
public class Java {
Toolkit toolkit;
Timer timer;
int t=10000,total;
public Java(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
total =seconds * t;
System.out.println(total);
timer.schedule(new RemindTask(), total);
}
class RemindTask extends TimerTask {
public void run() {
System.out.println("Time's up!");
toolkit.beep();
System.exit(0);
}
}
public static void main(String args[]) {
new Java(5);
System.out.println("Timer started");
}
}
How can I display the seconds similar to countdown timer in output screen, I want to use it in a quiz program
0:53 => 0:52 like this ...
What you can do is schedule a task at a fixed rate (Timer.scheduleAtFixedRate) using a period of 1 second. As far as possible, we should refrain from calling the System.exit(0) and wait for the threads to complete their tasks. We can make the main thread (the thread that started the timer) sleep for the duration of the timer tasks and then when it finally wakes up, it cancels the timer:
private final Timer timer;
public CountDownTimer(int seconds) {
timer = new Timer();
timer.scheduleAtFixedRate(new RemindTask(seconds), 0, 1000);
}
class RemindTask extends TimerTask {
private volatile int remainingTimeInSeconds;
public RemindTask(int remainingTimeInSeconds) {
this.remainingTimeInSeconds = remainingTimeInSeconds;
}
public void run() {
if (remainingTimeInSeconds != 0) {
System.out.println(remainingTimeInSeconds + " ...");
remainingTimeInSeconds -= 1;
}
}
}
public static void main(String args[]) throws InterruptedException {
CountDownTimer t = new CountDownTimer(5);
System.out.println("Timer started");
Thread.sleep(5000);
t.end();
}
private void end() {
this.timer.cancel();
}
I'm trying to stop a timer that ticks down from ten seconds to zero.
The problem is that the finish method only returns the first tick, rather than counting all the numbers down to one.
How can I make a boolean method return a value for every second rather than just the first?
import java.util.Timer;
import java.util.TimerTask;
public class Countdown {
static int interval;
static Timer timer;
boolean off;
public Countdown() {
int seconds = 10;
int delay = 1000;
int period = 1000;
timer = new Timer();
interval = seconds;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println(setInterval());
}
}, delay, period);
}
private int setInterval() {
off = false;
if (interval == 1){
timer.cancel();
off = true;
return --interval;
}else{
off = false;
return --interval;
}
}
public boolean finish(){
return off;
}
}
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public static void main(String[] args){
Countdown countDown = new Countdown();
countDown.finish()
System.out.println(countDown.finish);
if(countDown.finish() == true){
System.out.println("works");
}
}
If you want to write the value of finish every second, you should design your code to print it ever second, not just on startup...
ATM finish is only printed in the main-method and nowhere else. Move that line into the Runnable used by the Timer and it should print as expected.
Recently, I have been developing some android apps and I found that android.os.Handler class is very suitable for implementing a .NET Timer (By that I mean System.Windows.Forms.Timer and System.Timers.Timer).
If you don't know what a .NET timer is, it's a timer that can be stopped, started at any time and its interval can be changed any time.
So I did the following:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable () {
#Override
public void run() {
if (!paused) {
runnable.run ();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer () {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer () {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler ();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer ();
}
}
And it came out ok. Also, this one runs on the UI thread which means that I can use this to change graphical stuff. (I mainly use timers for those stuff)
However, this only works for android though. If I want to make a "traditional" java program, I have to use the stuff in the JDK. So I tried the following:
import java.util.Timer;
import java.util.TimerTask;
public class DotNetTimer {
private Timer timer;
private boolean paused;
private int interval;
private TimerTask task = new TimerTask () {
#Override
public void run() {
if (!paused)
runnable.run();
}
};
public Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
if (!paused) {
timer.cancel();
timer.scheduleAtFixedRate(task, interval, interval);
}
}
public void startTimer () {
timer.cancel();
timer.scheduleAtFixedRate(task, 0, interval);
}
public void stopTimer () {
paused = true;
}
public DotNetTimer (Runnable runnable, int interval, boolean started) {
timer = new Timer ();
this.runnable = runnable;
this.interval = interval;
if (started) {
paused = false;
startTimer ();
}
}
}
And I use this code to test it:
import static java.lang.System.out;
public class MyTestingClass {
static DotNetTimer timer;
public static void main(String[] args) {
Runnable r = new Runnable () {
int count = 0;
#Override
public void run() {
if (count < 5) {
count++;
out.println("Hello" + count);
} else {
timer.stopTimer();
}
}
};
timer = new DotNetTimer (r, 2000, true);
}
}
However, an IllegalStateException was thrown in the start timer method. I did some research on that and I found that java.util.Timer cannot be restarted after cancel(). And I know what you're saying, "why do you call cancel() in the startTimer() method?" If I don't call cancel(), the timer would have 2 tasks running when I call startTimer() when the timer is already started.
Any help will be appreciated.
From cancel() method in Timer class
Terminates this timer, discarding any currently scheduled tasks. Does
not interfere with a currently executing task (if it exists). Once a
timer has been terminated, its execution thread terminates gracefully,
and no more tasks may be scheduled on it.
Note that calling this method from within the run method of a timer
task that was invoked by this timer absolutely guarantees that the
ongoing task execution is the last task execution that will ever be
performed by this timer.
This method may be called repeatedly; the second and subsequent calls
have no effect.
so, internal thread of Timer is one-shot, you need to instantiate a new Timer object
You can check original source code of Timer class to understand (or replicate as you wish) how it really works
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java
I found out that there is a class in Android called Handler which can execute code with a delay. So I made use of this class to create a timer!
import android.os.Handler;
import android.support.annotation.NonNull;
import android.widget.TextView;
public class Timer implements Comparable<Timer> {
private Handler handler;
private boolean paused;
private TextView text;
private int minutes;
private int seconds;
private final Runnable timerTask = new Runnable () {
#Override
public void run() {
if (!paused) {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
}
text.setText (Timer.this.toString ());
Timer.this.handler.postDelayed (this, 1000);
}
}
};
#Override
public String toString () {
if (Integer.toString (seconds).length () == 1) {
return minutes + ":0" + seconds;
} else {
return minutes + ":" + seconds;
}
}
public void startTimer () {
paused = false;
handler.postDelayed (timerTask, 1000);
}
public void stopTimer () {
paused = true;
}
public void resetTimer () {
stopTimer ();
minutes = 0;
seconds = 0;
text.setText (toString ());
}
public Timer (TextView text) {
this.text = text;
handler = new Handler ();
}
public Timer (TextView text, String parseString) {
this (text);
String[] splitString = parseString.split (":");
minutes = Integer.parseInt (splitString[0]);
seconds = Integer.parseInt (splitString[1]);
}
#Override
public int compareTo(#NonNull Timer another) {
int numberOfSeconds = seconds + minutes * 60;
int anotherNumberOfSeconds = another.seconds + another.minutes * 60;
return ((Integer)numberOfSeconds).compareTo (anotherNumberOfSeconds);
}
}
And it has a really simple interface. Very easy to use.
I am trying to make a simple timer that plays a beep after the specified number of seconds. I managed to get it to work, but the TimerTask continues to run after the beep. Now do I stop execution?
Here is my code:
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;
class Alarm {
public static void main(String[] args) {
long delay;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a delay in seconds: ");
delay = scan.nextInt()*1000;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
Toolkit.getDefaultToolkit().beep();
}
};
timer.schedule(task, delay);
}
}
You need to cancel the timer by calling the following methods
timer.cancel(); // Terminates this timer, discarding any currently scheduled tasks.
timer.purge(); // Removes all cancelled tasks from this timer's task queue.
This will cancel the task, so something like this would work:
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;
class Alarm {
private static boolean run = true;
public static void main(String[] args) {
long delay;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a delay in seconds: ");
delay = scan.nextInt()*1000;
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
#Override
public void run() {
if(run) {
Toolkit.getDefaultToolkit().beep();
} else {
timer.cancel();
timer.purge();
}
}
};
timer.schedule(task, delay);
// set run to false here to stop the timer.
run = false;
}
}
Here is what worked for me (used the purge() suggestion also):
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;
class Alarm {
public static void main(String[] args) {
long delay;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a delay in seconds: ");
delay = scan.nextInt()*1000;
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
#Override
public void run() {
Toolkit.getDefaultToolkit().beep();
timer.cancel();
timer.purge();
}
};
timer.schedule(task, delay);
}
}
cancel() should do it - cancel stops the cancels the given TimerTask / Timer
isStart = true; // if true timmer function countiue called , else time canceled
Timer timer = new Timer();
timer.schedule(new TimerClass(), 0, 5000);
class TimerClass extends TimerTask {
public void run() {
if (isStart) {
yourFunction();
}else {
cancel();
}
}
}