comments on Executor

Doug Lea dl@cs.oswego.edu
Sat, 2 Feb 2002 16:18:50 -0500


Hi Mark,

If you do want something heavier than a simple cancelled bit,
you can actually interrupt the thread inside cancel. As in:

class MyRunnableTask extends RunnableTask {
  private Thread runner;

  public void run() {
    synchronized(this) {
      if (!isDone()) 
        runner = Thread.currentThread();
      else return;
    }
    action();
  }

  public synchronized void cancel() {
    if (!isDone()) return;
    super.cancel();
    if (runner != null)
      runner.interrupt();
  }
}

As mentioned before, you need to be sure that it is OK to actually
interrupt the thread, no matter what context the Runnable finds itself
being run in.  The main interaction with Executor classes is that any
interrupted thread should normally be discarded from the pool and
replaced with a fresh one. Doing this regularly makes thread pools
less efficient than using a thread per task. While there is no
guarantee that a given Executor implementation is faster/cheaper than
using threads, their typical much better performance when used for
running many short runnable tasks is one of the main reasons they are
used. I want to make sure that the required properties of all
Executors stay small, to ensure that very fast ones can still be
built, while still of course allowing implementations with extended,
heavier capabilities.

> Furthermore, if you look at what is coming up in jdk1.4 for java.nio.channels.Channel,
> it appears that sun is promising async interruption of IO.

I was on the nio JSR expert group. Yes, IO on nio channels really is
interruptible. If you discover otherwise, submit a bug report!

> .... and the fact that it still doesn't get me the critical code of how to share a pool
> of threads among multiple composites.
> I'd like to be able to have 4 composites of 5 tasks each to be all concurrent
> if i have a shared pool of 20 threads (or 21 to include a house-keeping thread).
> But if I have just 12 threads, i'd like that global limit to be enforced.
> At this point, i don't care about the scheduling algorithm (give each of the 4 composites
> 3 threads, or run 2 composites to completion at a time).
> 

I'm not sure what you mean here. Suppose you have something like:

class CompositeTask {
  void runAll(Executor exec) {
    for each task 
      exec.execute(task)
  }
  void cancelAll() {
    for each task 
      task.cancel();
  }
}

So you can use any number of CompositeTasks with the same executor,
and cancel each composite independently. Is there something else you
need?


> hmmm, well then maybe it'd help me if there were additional methods on Executor:
>   executeResult(Future result);

Good point. We'll strongly consider it.

-Doug