problem in implementing a timeout with Java

hi all

i wrote the following dummy class for implementing a timeout. Since in real case situations i cannot afford to create a new thread all the time, i am reusing the same one.

The code works as follows:the proceed() method check the currentTime and calculates what will be the endTime.

then the TimerThread is started, and meanwhile the class is looping in a while loop.

that while loop continues as long as two conditions are satisfied:

- the currentTime is not equal to the endTime: if that condition is not satisified, that means that we are in a timeout situation

- the TimerThread is still alive: if this condition is not satisfied that means that the job was finished in time (since at the end of run() the thread exits...

now, since i have to simulate a timeout, i used a variable called blocked that is incremented all the time. when blocked mod 3 == 0 then i make the TimerThread sleep so that a timeout is simulated.

what is funny is that:

- while the thread is sleeping, the caller class is still in the loop, and the currentTime is NOT incremented (as u will see on the screen by the printouts)

so at the end the timeout will never happens, and i cannot figure out why: i am NOT using any shared variables that can cause some sort of deadlock situation ..

here is my code, i hope that someone can find out what's wrong. i am suspected that it has to do with the fact that i am reusing the same thread all the time (since when i create a new one all the time it works fine)

import java.util.*;

import java.io.*;

public class TestTimer {

private Object proceedLock;

private boolean okToProceed;

private TimerThread timer;

private boolean started = false;

private int blocked = 1;

private boolean isStopped = false;

private boolean isCompleted = false;

public TestTimer() {

print("In TestTimer..");

timer = new TimerThread();

}

class TimerThread extends Thread {

private Thread runThread;

public boolean isCompleted = false;

public void doWork() {

run();

}

public void run() {

//System.err.println("WE ARE IN RUN METHODo: " + blocked);

runThread = Thread.currentThread();

try {

if((blocked % 3) == 0)

sleep(10000);

else {

isCompleted=true;

}

} catch(InterruptedException e) {}

}

public void stopThread() {

System.err.println("stopping the thread..");

if ( runThread != null)

runThread.interrupt();

}

}

public void proceed() throws Exception {

long startTime = System.currentTimeMillis();

long currentTime = startTime;

long endTime = startTime + 1000;

long testTime=0;

System.err.println("AT PROCEED: startTime is: " + startTime + " and endTime is: " + endTime);

if(timer.isAlive()) {

System.err.println("BEFORE EVERYTHING TIMER IS ALIVE!!");

}

if(!started) {

timer.start();

started=true;

} else {

timer.run();

}

while((currentTime < endTime) && (timer.isAlive())) {

currentTime = System.currentTimeMillis();

}

System.err.println("testTime: " + testTime);

if(timer.isAlive()) {

// this means that we are out because time has expired...

System.err.println("TIME HAS RUN OUT!");

timer.stop();

throw new Exception("there was a timeout..");

// stopping the thread..it's running for nothing..

}else {

System.err.println("we did it in time...");

System.err.println("currentTime: " + currentTime + "\t" + " endTime: " + endTime);

// we don't need to stop the thread because

// it's already over

}

blocked++;

}

private static void print(String msg) {

String name = Thread.currentThread().getName();

System.err.println(name + ": " + msg);

}

public static void main(String[] args) throws Exception {

final TestTimer timer = new TestTimer();

for(int i=0; i<3; i++) {

timer.proceed();

}

}

}

please help me soon

thanx in advance and regards

marco

[4285 byte] By [MmarcoM] at [2007-9-26 4:51:20]
# 1

Hi,

javax.swing.Timer class can be useful to have such timer functionality.

Test the same code removing the println statements in run(). As print() requires some IO, hence it consumes the time which should be used by the other thread...

print() functions ahould be avoided in multi threaded environment - specially when u use timer threads.

~Pacific

i_pacific at 2007-6-29 18:43:08 > top of Java-index,Core,Core APIs...
# 2

hi

it' s already removed....and i got still no luck.

i used thread because i want to be able to stop the timer, and also i don't want to create a new class all the time.

if u can give me a clue on how to implement the Timer with the javax.swing.Timer it will be appreciated.

thanx in advance and regards

marco

MmarcoM at 2007-6-29 18:43:08 > top of Java-index,Core,Core APIs...
# 3

hi all,

i solved it.

the problem was that i was not stopping the thread when it was exiting succesfully...

now it seems to work with this code

/*

* TestTimer.java

*

* Created on August 2, 2001, 9:58 AM

*/

import java.util.*;

import java.io.*;

public class TestTimer {

private Object proceedLock;

private boolean okToProceed;

private TimerThread timer;

private boolean started = false;

private int blocked = 0;

private boolean isStopped = false;

private boolean isCompleted = false;

public TestTimer() {

print("In TestTimer..");

timer = new TimerThread();

}

class TimerThread extends Thread {

private Thread runThread;

public boolean isCompleted = false;

public void doWork() {

run();

}

public void run() {

System.err.println("WE ARE IN RUN METHODo: " + blocked);

runThread = Thread.currentThread();

try {

if((blocked % 3) == 0)

this.sleep(15000);

else {

System.err.println("isCompleted=true");

}

} catch(InterruptedException e) {}

blocked++;

}

public void stopThread() {

System.err.println("stopping the thread..");

if ( runThread != null)

runThread.interrupt();

}

}

public void proceed() throws Exception {

for(int i=0; i < 7; i++) {

System.out.println("IN THE FOR FOR THE " + i + " time");

long startTime = System.currentTimeMillis();

long currentTime = startTime;

long endTime = startTime + 1000;

long testTime=System.currentTimeMillis();

System.err.println("AT PROCEED: startTime is: " + startTime + " and endTime is: " + endTime);

if(!started) {

timer.start();

started=true;

} else {

//timer.interrupt();

timer.start();

//timer.doWork();

}

System.err.println("before while.." + i );

while((currentTime < endTime) && (timer.isAlive())) {

//System.err.println("In the loop and blocked = " + blocked);

currentTime = System.currentTimeMillis();

}

System.err.println("AFter the loop. last currentTime = " + currentTime + " And now is: " + System.currentTimeMillis() + " and endTime was set to " + endTime);

if(timer.isAlive()) {

// this means that we are out because time has expired...

System.err.println("TIME HAS RUN OUT!");

timer.interrupt();

throw new Exception("there was a timeout..");

// stopping the thread..it's running for nothing..

}else {

timer.interrupt();

System.err.println("we did it in time.");

// we don't need to stop the thread because

// it's already over

}

}

}

private static void print(String msg) {

String name = Thread.currentThread().getName();

System.err.println(name + ": " + msg);

}

public static void main(String[] args) throws Exception {

TestTimer timer = new TestTimer();

//for(int i=0; i<3; i++) {

timer.proceed();

//}

}

}

regards

marco

MmarcoM at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...
# 4
Dude, if you are good enough to write your OWN timer class I am positive you would have no trouble using javax.swing.Timerorjava.util.Timer do you understand how to register a listener on the timer?
dnoyeB at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...
# 5

hi,

yeah...i know that listener stuff.... but in this special case i cannot use it.

i have already said previously that the operation to do must be encoded in the Timer itself.

so that already excluded the javax.swing.Timer

for sure i can use the other java.util.Timer, but that must spawn a new thread (althoug it's daemon) all the time.

and i cannot afford neither that

regards

marco

MmarcoM at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...
# 6
hi again sorry to say that the code that i supposed to work actually it does not because it seemsthat the thread does NOT go into the run() method.....i appreciate if anyone can help....thanx in advance and regardsmarco
MmarcoM at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...
# 7
hi again an additional thing i forgot to mention: i cannot use java.util.Timer since my customers hasJDK1.2.2_004 and the timer was introduced starting from JDK1.3hope tha tsomeone can help methanx in advance and regardsmarco
MmarcoM at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...
# 8

> hi again

> an additional thing i forgot to mention: i cannot

> t use java.util.Timer since my customers has

> JDK1.2.2_004 and the timer was introduced starting

> from JDK1.3

>

> hope tha tsomeone can help me

>

> thanx in advance and regards

> marco

What about javax.swing.timer?

so what if the timers are new. Just include the class anyway, its only 1 class. i think sun allows you to distribute the class.

dnoyeB at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...
# 9
to be clear, what I am saying is to compile with the version of java you need. then go and get the .class file which represents the timer. or you can get the java file and compile it into your project.
dnoyeB at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...
# 10

> hi again

> sorry to say that the code that i supposed to work

> k actually it does not because it seems

> that the thread does NOT go into the run()

> method.....

you can not use .start() to start a thread again, once the run() method finished, it'll never start again, in another word, the thread's already dead! To fix it, you should have a loop inside the run (say a while(true)), otherwise, you can never re-use a thread.

andy.g at 2007-6-29 18:43:09 > top of Java-index,Core,Core APIs...