[concurrency-interest] Advice for execute( Runnable task, longtimeout )

Joe Bowbeer jozart at blarg.net
Wed Apr 27 11:54:33 EDT 2005


Jan Nielsen writes:

> Joe, it looks to me like your idea behind the TimerTask approach is
> similar to my approach except you have separated the concerns nicely
> whereas I folded the two together - is that correct? (Though, it appears
> that a few modifications/extensions would also be required to implement
> this using your FutureResult and TimerTask, e.g., cancellation of the
> future result.)

I didn't study the details of your implementation, but I'll take your word 
for it :-)

I forgot that FutureResult didn't have cancel.  We used to work around this 
by calling setException.

  synchronized (future) {
    if (!future.isReady())
      future.setException(new InterruptedException());
  }


> I chose the latter for throughput though the former may be a more
> conservative approach.

The former provides an encapsulation at the Callable layer, which can be 
nice, but you pay a price in thread count.


Btw, I wrote:

>>All of these approaches have worked reasonably well for timeouts
>>within the range of human response times, i.e., none of these
>>solutions are suitable for precision work.

I should clarify that they work reasonably well on JVMs that are capable of 
running responsive GUIs.  That is, JVMs designed for use on the desktop.  As 
David points out, there are no fairness guarantees so none of these 
approaches (or thread.join or timer.schedule for that matter) may work well 
in other contexts (server, embedded).



----- Original Message ----- 
From: "Jan Nielsen" <jnielsen at sungardsct.com>
To: "Joe Bowbeer" <jozart at blarg.net>
Cc: <concurrency-interest at altair.cs.oswego.edu>
Sent: Wednesday, April 27, 2005 8:23 AM
Subject: Re: [concurrency-interest] Advice for execute( Runnable task, 
longtimeout )


Many thanks for the insights and suggestions, Joe and David.

I should have provided a little more context. My timeout values are
typically 5+/-2 seconds so the interruption sensitivity can be on the
order of a second without causing issues. The crux of the problem
motivating this request is limiting thread resources, which is why I did
not  use the TimedCallable though I considered changing TimedCallable to
use a ClockDaemon instead of the current thread-per-call approach. I
pursued the PooledExecutor implementation instead primarily because I
have an even-less-elegant version of it working (quite well) in
production and I, therefore, have confidence that it should work for
this particular problem.

Joe, it looks to me like your idea behind the TimerTask approach is
similar to my approach except you have separated the concerns nicely
whereas I folded the two together - is that correct? (Though, it appears
that a few modifications/extensions would also be required to implement
this using your FutureResult and TimerTask, e.g., cancellation of the
future result.)

It appears to me that the fundamental difference between the two
approaches is the number of cancel threads: one-per-request, or one. I
chose the latter for throughput though the former may be a more
conservative approach.

-Jan

Joe Bowbeer wrote:

>One thing I forget to point out:
>
>In a TimedCallable, the timer thread starts when the runnable *starts* to 
>execute, while the TimerTask starts at the moment the runnable is 
>*submitted* for execution.
>
>Another approach would be to have the runnable task schedule its own timer 
>task when it is started..
>
>All of these approaches have worked reasonably well for timeouts within the 
>range of human response times, i.e., none of these solutions are suitable 
>for precision work.
>
>
>Joe Bowbeer <jozart at blarg.net> wrote:
>
>
>>Jan Nielsen <jnielsen at sungardsct.com> wrote:
>>
>>
>>>I have a need in JVM 1.3 and above (Solaris, Windows, RedHat, and HPUX)
>>>for the following API in dl.util.concurrent.PooledExecutor.execute(
>>>Runnable command, long msecs) which interrupts a job if it's not
>>>complete after msecs. Snippits are shown below and a modified version
>>>PooledExecutor is attached. The implementation seems work but it feels
>>>like a hack, in particular the Worker, Work, and Interrupt class
>>>interaction seems less than ideal. Is there a better way to implement
>>>this in dl.util.concurrent? Any thoughts, suggestions, insights and/or
>>>critique are greatly appreciated.
>>>
>>>
>>>
>>Check out dl.util.concurrent.TimedCallable if you haven't already.
>>
>>This uses a dedicated thread per Callable, which may be too heavyweight 
>>for you, but at least you can execute it on a standard PooledExecutor.
>>
>>Callable callable = new Callable() {
>>  public Object call() {
>>    runnable.run();
>>    return Boolean.TRUE;
>>  }
>>}
>>
>>callable = new TimedCallable(callable, msecs);
>>
>>FutureResult future = new FutureResult();
>>Runnable setter = future.setter(callable);
>>
>>executor.execute(setter);
>>
>>
>>I would think something along these lines would also work:
>>
>>Callable callable = new Callable() {
>>  public Object call() {
>>    runnable.run();
>>    return Boolean.TRUE;
>>  }
>>}
>>
>>FutureResult future = new FutureResult();
>>Runnable setter = future.setter(callable);
>>
>>executor.execute(setter);
>>
>>TimerTask tt = new TimerTask() {
>>  public void run() {
>>    future.cancel();
>>  }
>>}
>>
>>timer.schedule(tt, msecs);
>>
>>Joe.
>>
>>
>>
>



More information about the Concurrency-interest mailing list