Re: Threading design question
Big Jim wrote:
<wesley.hall@gmail.com> wrote in message
news:1164381991.194419.150740@h54g2000cwb.googlegroups.com...
but I am calling interrupt() in the listener thread when I get a prompt
hence using the exception mechanism to break early from the sleep and go
and
process what's in th DB immediately, which is still normal processing:
You are right, it is not a big deal in the grand scheme of things, but
it would be slightly preferable to declare a class level field like
this...
private Object waitLock = new Object();
then do...
while(true)
{
try
{
synchronized(waitLock)
{
waitLock.wait(pollSeconds * 1000);
}
}
catch(InterruptedException ex)
{
log.info("Interrupted ...");
}
publisher.doProcessing();
}
Then to wake the thread do this...
synchronized(waitLock)
{
waitLock.notify();
}
This will do what you are doing but without throwing the
InterrupedException as a matter of course (it still could throw it
though, so you must handle this).
Thanks Wesley, that's the sort of thing I was thinking of, I guess I'd
provide the
synchronized(waitLock){waitLock.notify();}
in a public "wakeUp" method that my prompt listener could call instead of
interrupt() which would also remove the need for my processing class to be a
thread.
Just out of interest, which method do you think would be more efficient -
The one that's always using the execption handling mechanism by explicitly
calling interrupt() or the one with the synchronization overhead?
When designing an system, don't worry so much about overhead and speed.
Why? Once you have an easy to understand system in place, it is easier
to change small areas of the system without destroying others. Once
you have this, run a profiler. The profiler will tell you where your
system is taking the most time.
You would often be surprised by what actually takes time in your
system. I've been surprised many times myself. I once thought I was
going to have to find a new algorithm for drawing an arc, but it turned
out the delay was caused by a slow angle addition. It was a much
easier fix.
In any case, I think you'll still need a thread. waitLock.wait(time);
will block the thread that executes it. Also, wait isn't guarantied to
block the full time, even if no notify is called.
The best way to handle this is to have some sort of condition in a
loop.
public void waitToStartProcessing() throws InterruptedException {
long timeUntilEnd = System.currentTimeMillis() + pollSeconds *
1000;
while (System.currentTimeMillis() < timeUntilEnd) {
synchronized(waitLock) {
waitLock.wait(timeUntilEnd -
System.currentTimeMillis());
}
}
}
public void processWhenReady() throws InterruptedException {
waitToStartProcessing();
doProcessing();
}
public void forceProcessing() {
synchronized(waitLock) {
waitLock.notifyAll();
}
}
Hope this helps.
Daniel.