Home > Archive > Java Help > June 2007 > Need some guidance on using timer
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Need some guidance on using timer
|
|
| Hendrik Maryns 2007-06-12, 10:09 pm |
| -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi all,
I have this application which does a rather long computation, possibly
more than exponential in the input. I want to test how far I can go
within reasonable time. So I thought I’d have the program try to
compute stuff for ever bigger inputs, and see how far I got. This used
to work, since the main problem was space, so at a certain moment, an
OOME would occur, which I could catch and start again/continue.
However, now the space problem seems solved, and time is the main
factor. So I want to sort of limit the time the computation takes. I
sort of feel I need to use a Timer for this, and need a separate thread
which interrupts the main one after a certain time. However, I have no
experience at all with multithreading and using Timers, so I would be
very grateful for some guidance on how one could do this.
Sort of what I have in mind:
public void main(String... args) {
// create a thread which interrupts the main one
Thread interruptor = new Thread(new Runnable(){
//what should come here?
Thread.sleep(120000); // two minutes
//interrupt the main thread, and carry on with the next cycle
// what here?
notify(); // or something?
});
try {
// start my testing
test1();
} catch(InterruptedException e) {
// then, if the thread was interrupted, start with the next test
test2();
}
// and so on
}
TIA, H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGbmRae+7xMGD3itQRAtooAJ93SU8Mmh3H
i1PfXCe6aNxLCfQLIgCfTwap
EOORklM06wxD3pZp1H/ccLE=
=CgE3
-----END PGP SIGNATURE-----
| |
| Tom Hawtin 2007-06-12, 10:09 pm |
| Hendrik Maryns wrote:
>
> I have this application which does a rather long computation, possibly
> more than exponential in the input. I want to test how far I can go
> within reasonable time. So I thought I’d have the program try to
> compute stuff for ever bigger inputs, and see how far I got. This used
> to work, since the main problem was space, so at a certain moment, an
> OOME would occur, which I could catch and start again/continue.
> However, now the space problem seems solved, and time is the main
> factor. So I want to sort of limit the time the computation takes. I
> sort of feel I need to use a Timer for this, and need a separate thread
> which interrupts the main one after a certain time. However, I have no
> experience at all with multithreading and using Timers, so I would be
> very grateful for some guidance on how one could do this.
If you want to interrupt the main thread using the thread interrupt
mechanism, that's easy enough:
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
Thread interrupter = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(120*1000);
mainThread.interrupt();
} catch (java.lang.InterruptedException exc) {
// Just exit.
}
}
});
interrupter.setDaemon(true); // Shouldn't keep process alive.
interrupter.start(); // Important.
... do stuff ...
// Let the interrupted exit, if hasn't already.
interrupter.interrupt();
}
Of course that relies on your main code doing something interruptible:
waits/sleeps and, depending upon implementation, I/O. Interrupts can
also cause class loading to fails, at least theoretically.
If it's CPU, probably a better idea is to poll a volatile flag.
import java.util.concurrent.atomic.AtomicBoolean;
public static void main(String[] args) {
final AtomicBoolean stop = new AtomicBoolean();
final Thread mainThread = Thread.currentThread();
Thread interrupter = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(120*1000);
stop = true;
} catch (java.lang.InterruptedException exc) {
// Just exit.
}
}
});
interrupter.setDaemon(true); // Shouldn't keep process alive.
interrupter.start(); // Important.
... do stuff ...
if (stop.get()) {
break;
}
...
// Let the interrupted exit, if hasn't already.
interrupter.interrupt();
}
You can, of course, use java.util.Timer or
java.util.concurrent.ScheduledThreadPoolExecutor instead of the
Thread+sleep.
Tom Hawtin
| |
| Hendrik Maryns 2007-06-13, 7:26 pm |
| -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi Tom,
thanks for your answer, however... (see below)
Tom Hawtin schreef:
> Hendrik Maryns wrote:
>
> If you want to interrupt the main thread using the thread interrupt
> mechanism, that's easy enough:
>
> public static void main(String[] args) {
> final Thread mainThread = Thread.currentThread();
> Thread interrupter = new Thread(new Runnable() {
> public void run() {
> try {
> Thread.sleep(120*1000);
> mainThread.interrupt();
> } catch (java.lang.InterruptedException exc) {
> // Just exit.
> }
> }
> });
> interrupter.setDaemon(true); // Shouldn't keep process alive.
> interrupter.start(); // Important.
>
> ... do stuff ...
>
> // Let the interrupted exit, if hasn't already.
> interrupter.interrupt();
> }
>
> Of course that relies on your main code doing something interruptible:
> waits/sleeps and, depending upon implementation, I/O. Interrupts can
> also cause class loading to fails, at least theoretically.
Aha, I didn’t know that was necessary. It is definitely CPU that’s
going on. If I read
<http://java.sun.com/javase/6/docs/a....html#interrupt()>,
it is unclear that it is really necessary for the thread to be doing one
of those things. If it is simply running, only a boolean will be set,
which can be asked with Thread.isInterrupted(). That seems sort of the
same system as what you describe below.
However, I don’t like that, since it means I have to do a check in the
running thread. That doesn’t fit my purpose, though it is not
impossible, if need be.
Let me describe my scenario once again, maybe you can make another
suggestion? (Please :-})
I have a series of methods testFunction1(), testFunction2(), ..., which
sort of probe the limits of my program. They execute a loop which takes
longer each time. I want to know how many loops can be done in a fixed
time, say 2 minutes.
I want to do the following:
start testFunction1()
wait for 2 minutes, testFunction1 is running and eating CPU
cut off execution of testFunction1()
print some stats to standard out
start testFunction2()
and so on...
until all my testFunction()s are through, then stop.
Right now, it looks like this:
try {
testFunction1()
} catch (OutOfMemoryError e) {
System.gc();
System.out.println("OOME!");
}
try {
testFunction2()
} catch (OutOfMemoryError e) {
System.gc();
System.out.println("OOME!");
}
....
this works, since until recently, memory was the main problem in the
functions. However, I applied some nice tricks (hum), and now memory is
no longer the problem, but rather execution time. So something similar,
which, instead of waiting for an OOME, waits for X minutes, then breaks
off execution, and start the next one.
In short: it would be nice if I wouldn’t need the testing for the flag
(be it a volatile of Thread.isInterrupted()). Any ideas?
> If it's CPU, probably a better idea is to poll a volatile flag.
>
> import java.util.concurrent.atomic.AtomicBoolean;
>
> public static void main(String[] args) {
> final AtomicBoolean stop = new AtomicBoolean();
> final Thread mainThread = Thread.currentThread();
> Thread interrupter = new Thread(new Runnable() {
> public void run() {
> try {
> Thread.sleep(120*1000);
> stop = true;
> } catch (java.lang.InterruptedException exc) {
> // Just exit.
> }
> }
> });
> interrupter.setDaemon(true); // Shouldn't keep process alive.
> interrupter.start(); // Important.
>
> ... do stuff ...
> if (stop.get()) {
> break;
> }
> ...
>
> // Let the interrupted exit, if hasn't already.
> interrupter.interrupt();
> }
>
> You can, of course, use java.util.Timer or
> java.util.concurrent.ScheduledThreadPoolExecutor instead of the
> Thread+sleep.
I don’t really see how. It basically is the same, right? One would
need to write a TimerTask which sets the flag. Ok.
H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGcCZFe+7xMGD3itQRAs87AJ9vmxNSaD55
xWqzFsZBF3meR02+owCggLhA
u+Z9li3/+YqUHfSqT6r0pKA=
=Dbbm
-----END PGP SIGNATURE-----
| |
| Patricia Shanahan 2007-06-13, 7:26 pm |
| Hendrik Maryns wrote:
....
> Right now, it looks like this:
>
> try {
> testFunction1()
> } catch (OutOfMemoryError e) {
> System.gc();
> System.out.println("OOME!");
> }
>
> try {
> testFunction2()
> } catch (OutOfMemoryError e) {
> System.gc();
> System.out.println("OOME!");
> }
>
> ...
>
> this works, since until recently, memory was the main problem in the
> functions. However, I applied some nice tricks (hum), and now memory is
> no longer the problem, but rather execution time. So something similar,
> which, instead of waiting for an OOME, waits for X minutes, then breaks
> off execution, and start the next one.
....
Here are a couple of random suggestions, completely untested:
1. Try Thread.stop. I know it is deprecated, and understand the reasons,
but if I understand the situation this is rather experimental, so it may
be worth taking a risk.
2. Run the test function in a separate Process, and call its kill method.
In both cases, you need to make sure that the test function does things
to force its progress to be visible. That is an inherent consequence of
running it in a separate thread, and killing that thread. If you force
all activity to be continuously visible to other threads, your test code
will be running artificially slowly, using main memory too much and
registers too little.
Given that need to force visibility of progress, why not just check the
time at each report point and terminate tidily when it is after a
specified limit?
Patricia
| |
| Hendrik Maryns 2007-06-14, 10:10 pm |
| -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Tom Hawtin schreef:
> Hendrik Maryns wrote:
>
> Using Thread.interrupt does much the same, only that also interferes
> with wait/sleep and I/O. You also have the problem that badly written
> code can swallow the signal. Lots of code looks something like:
>
> } catch (java.lang.InterruptedException exc) { // BAD !!
> }
>
>
> If it's just a quick hack, then you can use Thread.stop. But that is
> deprecated for very good reasons.
>
> Is it really too difficult to poll a flag?
Thank you both. I read the document about Thread.stop() now, and I
understand why it is deprecated. And indeed, Sun suggests the same
solution as you did, so I guess that really is the way.
No it is not too difficult, it just clutters up stuff a little. But
I’ll have to live with that and it is testing code only anyway.
Cheers, H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGcQ2we+7xMGD3itQRArZ4AJwPd1wBBett
MwFIpc5bE84mNT+SEwCbBh7n
5k1K0rqrcFJAREOGMcxce4o=
=sHkj
-----END PGP SIGNATURE-----
| |
| Hendrik Maryns 2007-06-14, 10:10 pm |
| NNTP-Posting-Host: lichtenstein.sfb.uni-tuebingen.de
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
X-Trace: newsserv.zdv.uni-tuebingen.de 1181821289 7128 134.2.147.26 (14 Jun 2007 11:41:29 GMT)
X-Complaints-To: usenet@newsserv.zdv.uni-tuebingen.de
NNTP-Posting-Date: Thu, 14 Jun 2007 11:41:29 +0000 (UTC)
User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); nl; rv:1.8.1.3) Gecko/20070326 Thunderbird/2.0.0.0 Mnenhy/0.7.5.666
In-Reply-To: <f4r2h3$sbu$1@newsserv.zdv.uni-tuebingen.de>
X-Enigmail-Version: 0.95.1
Bytes: 4122
Xref: number1.nntp.dca.giganews.com comp.lang.java.help:287192
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hendrik Maryns schreef:
> Tom Hawtin schreef:
>
>
>
>
> Thank you both. I read the document about Thread.stop() now, and I
> understand why it is deprecated. And indeed, Sun suggests the same
> solution as you did, so I guess that really is the way.
>
> No it is not too difficult, it just clutters up stuff a little. But
> Ill have to live with that and it is testing code only anyway.
After some fiddling around, I came with a much easier solution, no need
for multithreading at all: just measure how long the computation takes,
it is above a certain threshold, just stop:
final int mins = 1;
boolean stop = false;
while (!stop) {
.... initialize ...
time = System.currentTimeMillis();
builder.visit(conj); // this is the method that takes a lot of time
time = System.currentTimeMillis() - time;
.... print some statistics ...
if (time > mins * 60 * 1000) {
stop = true;
}
}
System.out.println("stopped since last loop took more than " + mins +
" min");
Heh, could have thought of that myself. I am sorry I you all
by starting about threads and stuff.
Cheers, H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGcRrZe+7xMGD3itQRApvOAJwPrwnGU8Sg
9GHRQ6xTobudtwWGywCeM8Yh
hQG9z+erb2Y9xn67JHN6+vg=
=qBSF
-----END PGP SIGNATURE-----
|
|
|
|
|