I am trying to execute a task periodically. For example:
class MyTimerTask implements TimerTask
{
public void run() {
// Some actions to perform
}
Timer cleaner = new Timer(true);
cleaner.scheduleAtFixedRate(new MyTimerTask(), 0, PURGE_INTERVAL);
}
However, the run method is executing only once. But if I put the first time delay as 10 seconds, then the run method doesn't execute even once.
Example:
cleaner.scheduleAtFixedRate(new MyTimerTask(), 10, PURGE_INTERVAL);
This sounds like an issue with time units to me. Ensure that you're converting to milliseconds correctly.
The easiest way to do this is to use Java's TimeUnit.
Timer cleaner = new Timer(true);
cleaner.scheduleAtFixedRate(new MyTimerTask(),
TimeUnit.SECONDS.toMillis(10),
TimeUnit.SECONDS.toMillis(30));
It could also be caused by the Timer being started in daemon mode. If all your main method does is set up the timer and then return the timer will never execute since it's the last remaining thread and because it's a daemon thread the JVM will exit.
To fix this either make the timer thread not a daemon (i.e. pass false in the constructor) or make the main thread wait for user input before exiting.
Here's an example using both of the above:
public class TimerDemo extends TimerTask {
public void run() {
System.out.printf("Time is now %s%n", LocalTime.now());
}
public static void main(String[] args) throws IOException {
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerDemo(),
TimeUnit.SECONDS.toMillis(5),
TimeUnit.SECONDS.toMillis(10));
System.out.printf("Program started at %s%n", LocalTime.now());
System.out.println("Press enter to exit");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
// Wait for user to press enter
reader.readLine();
}
System.out.println("Bye!");
}
}
And output of running it:
Program started at 14:49:42.207
Press enter to exit
Time is now 14:49:46.800
Time is now 14:49:56.799
Time is now 14:50:06.799
Time is now 14:50:16.799
Time is now 14:50:26.799
[I pressed 'enter']
Bye!
Process finished with exit code 0
I had a hard time figuring out exactly what is your problem, so this might not be exactly what you are asking for, but this solution might fit you:
public class MyTimerTask implements Runnable {
private static final TimeUnit timeUnit = TimeUnit.SECONDS;
private final ScheduledExecutorService scheduler;
private final int period = 10;
public static void main(String[] args) {
new MyTimerTask();
}
public MyTimerTask() {
scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(this, period, period, timeUnit);
}
#Override
public void run() {
// This will run every 10 seconds
System.out.println("Ran...");
}
}
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 am writing a program in java where after x amount of time without any input from the user, it does shutdown like System.exit(0). Does anyone know how can I do this?
Use a Timer class and add a timer schedule task into it which will act like an exit process. Once timer up, exit the program.
public static void main(String[] args) throws InterruptedException {
final long thresholdTime = 11 * 1000;//in seconds
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("Game Over. Couldn't cancel the time bomb.... Booommm.");
System.exit(0);
}
}, thresholdTime);
// Normall processing of program...
//TimeUnit.SECONDS.sleep(10);
// When you think you are good with your inputs.. call this
timer.cancel();
}
In my main thread I send some data to server via HttpURLConnection, then I start a timer to execute a TimerTask periodically to check the response of server. When I get the expected string I call timer.cancel(). After this, main thread resume from where the timer is started.
I imagine following simplified code with the same mechanism just for this post:
public class Test {
public static void main(String[] args) throws InterruptedException {
System.out.println("start");
Timer timer = new Timer();
TmTask timerTask = new TmTask(timer);
Thread thread = new Thread(timerTask,"thread_1");
thread.start();
thread.join();
System.out.println("end");
}
}
class TmTask extends TimerTask{
Timer t;
public TmTask(Timer t){
this.t = t;
}
#Override
public void run() {
t.schedule(new A(t), 100, 1000);
}
}
class A extends TimerTask{
private Timer t;
private int i = 0;
public A(Timer t) {
this.t = t;
}
#Override
public void run() {
System.out.println("abc" );
i++;
if (i == 3) t.cancel();
}
}
My expection is :
start
abc
abc
abc
end
But I get:
start
end
abc
abc
abc
Finally I realized that in my code there are 3 threads created but I expected 2 (main thread, and Timer thread), and the join() method works on the thread named thread_1 instead of the timer thread. But I have no idea how to improve it.
Can anyone help me? Thanks in advance.
The whole purpose of creating a new Thread is to start it separately from the main thread - to get parallel execution. You got 3 threads because the timertask creates its own thread. If you want your current (main) thread to stop and wait for result then you can just do something like:
boolean result = false;
while( ! result ) {
result=checkForResult();
Thread.sleep(1000);
}
This will pause the current thread and cause it to block. Usually for such external tasks and async calls you DO NOT want the main thread to stop execution and wait because you don't know when will you get result and it might wait indefinitely. So probably your result is the desired one? :)
I am quite new to Java and I'm trying to generate a task that will run every 5 to 10 seconds, so at any interval in the area between 5 to 10, including 10.
I tried several things but nothing is working so far. My latest effort is below:
timer= new Timer();
Random generator = new Random();
int interval;
//The task will run after 10 seconds for the first time:
timer.schedule(task, 10000);
//Wait for the first execution of the task to finish:
try {
sleep(10000);
} catch(InterruptedException ex) {
ex.printStackTrace();
}
//Afterwards, run it every 5 to 10 seconds, until a condition becomes true:
while(!some_condition)){
interval = (generator.nextInt(6)+5)*1000;
timer.schedule(task,interval);
try {
sleep(interval);
} catch(InterruptedException ex) {
ex.printStackTrace();
}
}
"task" is a TimerTask. What I get is:
Exception in thread "Thread-4" java.lang.IllegalStateException: Task already scheduled or cancelled
I understand from here that a TimerTask cannot be reused, but I am not sure how to fix it. By the way the my TimerTask is quite elaborate and lasts itself at least 1,5 seconds.
Any help will be really appreciated, thanks!
try
public class Test1 {
static Timer timer = new Timer();
static class Task extends TimerTask {
#Override
public void run() {
int delay = (5 + new Random().nextInt(5)) * 1000;
timer.schedule(new Task(), delay);
System.out.println(new Date());
}
}
public static void main(String[] args) throws Exception {
new Task().run();
}
}
Create a new Timer for each task instead, like you already do: timer= new Timer();
And if you want to synchronize your code with your threaded tasks, use semaphores and not sleep(10000). This might work if you're lucky, but it's definitely wrong because you cannot be sure your task has actually finished.
I have a question about the behaviour of Timer class in Java.
This is the code: http://pastebin.com/mqcL9b1n
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.foo();
m = null;
}
public void foo() {
Timer t = new Timer();
t.schedule(new SysPrint(), 200);
}
}
class SysPrint extends TimerTask {
public void run() {
System.out.println("Yes!");
}
}
What happens is that if you run that program, it will print "Yes!" and it's not gonna do anything else (the program doesn't end).
The Java documentation says:
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection).
As I see this thing, the "last live reference" to the Timer object is gone after the 'foo()' functions ends. And the only task scheduled was the "Yes!" task that was executed, so I guess that after the process printed "Yes!", the Timer object should end and the process should terminate.
What happened here?
Java is not exiting because your thread running the Timer is still kicking around. You have to mark that thread as being a daemon thread before Java will exit. You probably don't have access to the thread itself so unless Timer has a method to mark it so you'll have a hard time doing that. You'll need to manually stop it in a finally clause.
try {
timer = new Timer();
timer.schedule( new SysPrint(), 200 );
} finally {
timer.cancel();
}
I believe the code below should do the trick.
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.foo();
m = null;
}
public void foo() {
Timer t = new Timer();
t.schedule(new SysPrint(), 200);
}
}
class SysPrint extends TimerTask {
SysPrint(Timer timer) {
this.timer = timer;
}
public void run() {
System.out.println("Yes!");
timer.cancel();
}
private Timer timer;
}
When you create a Timer object. A TimerThread is created. And it the internal thread to run your task. You can view the method run() of TimerThread. You can see it has a while loop.
private void mainLoop() {
while (true) {....
The TimerThread not set to a daemon, so the main method execute completely, the jvm not exists.
That why your program is always running and don't stop.