[concurrency-interest] BackPort: Threads not under control

Joe Bowbeer joe.bowbeer at gmail.com
Wed May 24 15:17:53 EDT 2006


Srini,

Strictly speaking, you want to call isTerminated instead of isShutdown
at the end, but I suspect it will also return true.

I suspect the source of your trouble is that the executing tasks are
not responding to interrupts.

invokeAll will cancel tardy tasks via task.cancel(true).  This will
set the task's state to cancelled and will also interrupt the task's
worker thread.  But the task's Callable/Runnable has to respond to the
interrupt (or at least the cancellation) in order for it to actually
stop.  Otherwise, if it ignores the interrupt, say, then it will run
to completion regardless.  The additional cancel(true) handling in
your code is probably wasted effort...


How to tell if a Callable is responsive to interrupts?

Check out the way the Callable<Integer> handles interrupt here:

http://java.sun.com/docs/books/tutorial/essential/threads/pool.html

    public Integer call() {
        for (int i = 0; i <= 100; i += 20) {
            //Perform some work...
            System.out.format("Worker number: %d, percent complete: %d%n",
                workerNumber, i);
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {}
        }
        return(workerNumber);
    }

This is a *good* example of how *not* to respond to an interrupt :-(


To be responsive to interrupt, the task should be written as:

    public Integer call() {
        try {
            for (int i = 0; i <= 100; i += 20) {
                //Perform some work...
                System.out.format("Worker number: %d, percent complete: %d%n",
                    workerNumber, i);
                Thread.sleep((int)(Math.random() * 1000));
            }
        } catch (InterruptedException e) {}
        return(workerNumber);
    }


OR I prefer to simply declare the InterruptedException:

    public Integer call() throws InterruptedException {
        for (int i = 0; i <= 100; i += 20) {
            //Perform some work...
            System.out.format("Worker number: %d, percent complete: %d%n",
                workerNumber, i);
            Thread.sleep((int)(Math.random() * 1000));
        }
        return(workerNumber);
    }

--Joe


On 5/24/06, Srini Pillai <SPILLAI at mail.nysed.gov> wrote:
> Hi all,
>
> We are using the Concurrent package (backport) in a J2ee application
> which spans several threads to connect with various other sources for
> information. I was skeptical to use this package on a J2ee application
> due to the popular notion that custom multithreading is not recommended
> on J2ee apps. Some people convinced me that this package has more APIs
> to control the Threads created.
>
> Now coming to the real problem, below is the block of code I use to
> start the various tasks and control them...
>
>                 ExecutorService service =
> Executors.newCachedThreadPool();
>                 List futures = service.invokeAll(tasks, 20,
> TimeUnit.SECONDS);
>                 Iterator futuresIter = futures.iterator();
>                 while (futuresIter.hasNext()) {
>                     Future future = (Future) futuresIter.next();
>                     try {
>                           searchResults = future.get();
>                     } catch(CancellationException ce) {
>                         log.warn("Task timed out. Exception Message: "
> + ce);
>                         future.cancel(true);
>                     } catch(Exception e) {
>                         log.warn("Exception occurred for a task.
> Exception Message: " + e);
>                         future.cancel(true);
>                     }
>                 }
>             }
>             service.shutdownNow();
>             System.out.println("SHUTDOWN ? " + service.isShutdown());
>             .....
>
>
> The 'tasks' that is called in the 'service.invoke()' are a list of
> Callable implementations. When a Future task is timedout, as specified
> in the invoke() method, control comes back to the exception but the
> actual task still executes until it is terminated. The last stmt
> (System.out) shows 'true', eventhough the task keeps executing until it
> is dead. From the API declaration I believe the service tries to call
> interrupt on this task but is it true that it cannot guarantee that the
> task will stop and that shutdown will not always cause the task to stop
> ? Please advice. Also let me know if I am missing something... Really
> appreciate your help...
>
> Thanks,
> Srini



More information about the Concurrency-interest mailing list