[concurrency-interest] BackPort: Threads not under control

Srini Pillai SPILLAI at MAIL.NYSED.GOV
Wed May 24 16:54:49 EDT 2006


Joe,

Thanks for the explaination. I found out that the task I was running
(which is an I/O operation, a socket connection) is not interrupted
properly. To respond to the interrupt call I had to place a dummy
Thread.sleep(1) in the loop that is performing the I/O to trap the
Interrupt. This throws the exception and stops the thread but I don't
like the idea of having the Thread.sleep() there... Is there a different
way to trap the interrupt ?

Thanks,
Srini

>>> "Joe Bowbeer" <joe.bowbeer at gmail.com> 5/24/2006 3:17 PM >>>
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

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest at altair.cs.oswego.edu 
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest


More information about the Concurrency-interest mailing list