I was wondering if someone might be able to see what I had done wrong here. I am trying to create a timer which will increment the count variable by 1 every second and print it out on the console. However, it prints the first number and then stops and I am not sure what is going on.
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest {
private Timer timer;
public int count = 0;
public TimerTest() {
timer = new Timer();
timer.schedule(new TimerListener(), 1000);
}
private class TimerListener extends TimerTask {
#Override
public void run() {
count++;
System.out.println(count);
}
}
public static void main(String[] args) {
new TimerTest();
}
}
I did find some other questions like this but none of their solutions made any difference to the result.
Thanks.
Your scheduling only runs the task once. You need to add a parameter to use the method schedule(TimerTask task,
long delay,
long period):
timer.schedule(new TimerListener(), 1000, 1000);
Related
I am writing a web crawler and part of the specifications is that it will crawl the web for a user-specified amount of time. In order to do that I am trying to use the Timer and TimerTask methods. The code I have now is attempt number two. I have watched a few tutorials though none of them are quite what I need. I have also read through the documentation. I have been working on this project for a few weeks now and it is due tonight. I am not sure where to turn to next.
public void myTimer (String url, long time)
{
Timer webTimer = new Timer();
TimerTask timer;
timer = new TimerTask()
{
public void run()
{
long limit = calculateTimer(time);
while(System.currentTimeMillis() < limit)
{
webcrawler crawler1 = new webcrawler();
crawler1.Crawl(url);
}
System.out.println("times Up");
}
};
webTimer.schedule(timer, 1000);
}
I am guessing the .Crawl() is starting a loop and keeping that thread busy, which means it cannot check the while condition. I do not know your implementation of the crawler but i would recommend a function stopCrawling which would set a boolean to true to break the loop inside that class. Than I would do something like this:
public void startCrawler (String url, long time){
webcrawler crawler1 = new webcrawler();
crawler1.Crawl(url);
TimerTask task = new TimerTask() {
public void run() {
crawler1.stopCrawling()
}
};
Timer timer = new Timer("Timer");
timer.schedule(task, time);
}
I have a function foo().
I want to call foo() every 5 seconds, and after "X" calls of foo() call it every 4 seconds. After another "X" calls of foo() every 3 seconds until foo is called every second.
I also need to be able to stop calling foo at anytime.
I have looked through other Stack Overflow posts and have not found anything that allows me to change the interval of calling dynamically.
What can I do?
Have a look at Timerand TimerTask classes in Java. You can schedule a TimerTask and have the task decide when it is scheduled the next time. The task schedules itself.
This way you can dynamically decide for the next execution interval.
import java.util.Timer;
import java.util.TimerTask;
public class Main {
public interface FooService {
public void foo();
}
public static class DelayCalculator {
public long nextTime() { // ... };
}
public static class FooTask extends TimerTask {
FooService fooSvc;
public FooTask(FooService foos) {
fooSvc = foos;
}
#Override
public void run() {
fooSvc.foo();
TIMER.schedule(new FooTask(fooSvc), DELAYCALC.nextTime());
}
}
private static final Timer TIMER = new Timer();
private static final DelayCalculator DELAYCALC = new DelayCalculator();
public static void main(String[] args) {
FooTask fooT = new FooTask(() -> System.out.println("Foo"));
TIMER.schedule(fooT, 0);
}
}
Set a timer (either via Alarm of Handler) for every 5 seconds. Keep a track of how many times its been called. When that number is higher than X, change the timer to every 4 seconds. When its higher than 2*X, change it to 3. Etc.
I have a game where I am scheduling a timer. I have this CoresManager file:
package com.rs.cores;
import java.util.Timer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public final class CoresManager {
protected static volatile boolean shutdown;
public static WorldThread worldThread;
public static ExecutorService serverWorkerChannelExecutor;
public static ExecutorService serverBossChannelExecutor;
public static Timer fastExecutor;
public static ScheduledExecutorService slowExecutor;
public static int serverWorkersCount;
public static void init() {
worldThread = new WorldThread();
int availableProcessors = Runtime.getRuntime().availableProcessors();
serverWorkersCount = availableProcessors >= 6 ? availableProcessors - (availableProcessors >= 12 ? 7 : 5) : 1;
serverWorkerChannelExecutor = availableProcessors >= 6 ? Executors
.newFixedThreadPool(availableProcessors - (availableProcessors >= 12 ? 7 : 5),
new DecoderThreadFactory()) : Executors.newSingleThreadExecutor(new DecoderThreadFactory());
serverBossChannelExecutor = Executors
.newSingleThreadExecutor(new DecoderThreadFactory());
fastExecutor = new Timer("Fast Executor");
slowExecutor = availableProcessors >= 6 ? Executors.newScheduledThreadPool(availableProcessors >= 12 ? 4 : 2,
new SlowThreadFactory()) : Executors
.newSingleThreadScheduledExecutor(new SlowThreadFactory());
worldThread.start();
}
public static void shutdown() {
serverWorkerChannelExecutor.shutdown();
serverBossChannelExecutor.shutdown();
fastExecutor.cancel();
slowExecutor.shutdown();
shutdown = true;
}
private CoresManager() {
}
}
I am using this inside the game:
private void startTimer() {
CoresManager.fastExecutor.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (timer == 0 || timer < 1) {
player.sm("Your timer has ended! The NPCs will no longer spawn.");
timer = 0;
this.cancel();
exitInstance();
return;
}
timer--;
timerchecker = true;
seconds = timer % 60;
player.setTimer(timer);
minutes = TimeUnit.SECONDS.toMinutes(timer);
}
}, 0, 1000);
}
The CoresManager Timer stops running if the player logs out AND the server gets rebooted. To make it run again, I added a code to make it do startTimer() again once you log back in. However, since the timer still runs if the server didn't log out, the timer starts running twice. The Timer starts getting subtracted by 2, or more, depending on how many times you log out and in. I figure that it would fix if there was a code to determine if the timer is already running. Is there a way to do this? Please help!
I don't see anything in the documentation that provides for checking the status on a TimerTask object (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/TimerTask.html) so one option would be to extend TimerTask and create your own class. Instead of using an anonymous TimerTask, you could create something along the lines of:
public class CoresTimerTask extends TimerTask {
private boolean hasStarted = false;
#Overrides
public void run() {
this.hasStarted = true;
//rest of run logic here...
}
public boolean hasRunStarted() {
return this.hasStarted;
}
}
and just maintain a reference to this CoresTimerTask object, which you then pass into startTimer(). You can then later check this object via hasRunStarted.
public long scheduledExecutionTime()
Returns the scheduled execution time of the most recent actual execution of this task. (If this method is invoked while task execution is in progress, the return value is the scheduled execution time of the ongoing task The return value is undefined if the task has yet to commence its first execution.
This method is typically not used in conjunction with fixed-delay execution repeating tasks, as their scheduled execution times are allowed to drift over time, and so are not terribly significant.
first thing periodically running tasks need set/reset state flag
second (when i look at examples) it is better to seal this type of class
but if someone insist to have such methods
public abstract class NonInterruptableTask extends TimerTask {
protected boolean isDone = false;
public boolean isDone() {return isDone;}
protected abstract void doTaskWork();
#Override
public void run() {
isDone = false;
doTaskWork();
isDone = true;
}
}
usage:
TimerTask myTask = new NonInterruptableTask() {
#Override
public void doTaskWork() {
//job here
}
};
you could also declare a boolean state called like "timerstate" or whatever and make it by default to be false. whenever you start a timer you could change this boolean to true and you'd be able to keep track of the timer.
public boolean timerstate;
public Timer t1;
// some code goes here to do whatever you want
if(timerstate == true) {
t1.cancel();
t1.purge();
t1 = new Timer();
} else{
t1.schedule(new TimerTask() {
#Override
public void run() {
timerstate = true;
//rest of code for the timer goes here
}
}
}
Being a fan of the Pomodoro technique I'm making myself a countdown timer to keep me on task with my homework. This particular project, however, is NOT homework. :)
Stack has a LOT of questions about using timers to control delays before user input and the like, but not a lot on standalone timers. I've run across this code from a friend, and have studied the class on Java Documentation.
public class Stopwatch {
static int interval;
static Timer timer;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Input seconds => : ");
String secs = sc.nextLine();
int delay = 1000;
int period = 1000;
timer = new Timer();
interval = Integer.parseInt( secs );
System.out.println(secs);
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}, delay, period);
}
private static final int setInterval()
{
if( interval== 1) timer.cancel();
return --interval;
}
}
There is some syntax that's not clear to me. Consider:
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}, delay, period);
I'm not understanding how the parentheses and braces work. At first glance, given the usage of scheduleAtFixedRate(TimerTask task, long delay, long period) I can see the delay and period parameters, but not an open paren preceding first parameter.
Is my first parameter actually this whole block of code? I would expect the whole block to be surrounded by parentheses...but it's not. Is this a common syntax in java? I've never run across it before.
new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}
I just want to clarify that I understand it before I start mucking about with changes.
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}, delay, period);
That code is equivalent to this refactoring, where the new TimerTask is assigned to a local variable.
TimerTask task = new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
};
timer.scheduleAtFixedRate(task, delay, period);
Of course the weird part has just moved upwards a bit. What is this new TimerTask stuff, exactly?
Java has special syntax for defining anonymous inner classes. Anonymous classes are a syntactical convenience. Instead of defining a sub-class of TimerTask elsewhere you can define it and its run() method right at the point of usage.
The code above is equivalent to the following, with the anonymous TimerTask sub-class turned into an explicit named sub-class.
class MyTimerTask extends TimerTask
{
public void run()
{
System.out.println(setInterval());
}
}
TimerTask task = new MyTimerTask();
timer.scheduleAtFixedRate(task, delay, period);
You are correct, the first parameter is the entire code block:
new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}
These declarations are called Anonymous classes and are explained in more detail in the Java Tutorials.
It is a anonymous inner class. You need to study inner classes for understanding this. Generally such classes are used when you do not need the class to be used else where in your code. You cannot use it else where just because you dont have reference pointing to it.
You can also replace the above code as follows :
class MyTimerTask extends TimerTask {
#Override
public void run() {
// Timer task code goes here.
System.out.println(setInterval());
}
}
MyTimerTask timerTask = new MyTimerTask();
timer.scheduleAtFixedRate(timerTask, delay, period);
I was looking for a Java timer sample and found the code below at
http://www.javaprogrammingforums.com/java-se-api-tutorials/883-how-use-timer-java.html
But if you run the sample, although it does print Timer stops now... it does not return to the command prompt. This is at least what is happening on my Windows XP machine using cmd.exe.
Why does it not return control to the prompt in this case?
import java.util.Timer;
import java.util.TimerTask;
public class TimerSample {
public static void main(String[] args) {
//1- Taking an instance of Timer class.
Timer timer = new Timer("Printer");
//2- Taking an instance of class contains your repeated method.
MyTask t = new MyTask();
//TimerTask is a class implements Runnable interface so
//You have to override run method with your certain code black
//Second Parameter is the specified the Starting Time for your timer in
//MilliSeconds or Date
//Third Parameter is the specified the Period between consecutive
//calling for the method.
timer.schedule(t, 0, 2000);
}
}
class MyTask extends TimerTask {
//times member represent calling times.
private int times = 0;
public void run() {
times++;
if (times <= 5) {
System.out.println("I'm alive...");
} else {
System.out.println("Timer stops now...");
//Stop Timer.
this.cancel();
}
}
}
It does not return to your command prompt because it is not expected to do so.
Timer creates single non-deamon thread to run all tasks. It does not terminate the thread unless you ask it. When you execture task.cancel() method you just cancel the current task, not the whole timer which is still alive and is ready to do something else.
To terminate timer you should call its stop() method, i.e. timer.stop();
In a real program you would keep a copy of the timer object and when eg program is to be closed down do a timer.cancel().
For this simple example, I added the code below after timer.schedule(t, 0, 2000);
try {
Thread.sleep(20000);
} catch(InterruptedException ex) {
System.out.println("caught " + ex.getMessage());
}
timer.cancel();
}
You need to explicitly terminate the Timer using timer.cancel(), e.g.:
class MyTask extends TimerTask {
private int times = 0;
private Timer timer;
public MyTask(Timer timer) {
this.timer = timer;
}
public void run() {
times++;
if (times <= 5) {
System.out.println("I'm alive...");
} else {
System.out.println("Timer stops now...");
//Stop Timer.
this.cancel();
this.timer.cancel();
}
}
}