logo       

Questions about ThreadPoolExecutor and possible loss of 'command': msg#00040

java.jsr.166-concurrency

Subject: Questions about ThreadPoolExecutor and possible loss of 'command'

Hi,
I have couple of questions on ThreadPoolExecutor

Per documentation, ThreadPoolExecutor will not create new threads if corePoolSize threads are running instead new tasks are queued in the workQueue. Then there is no usage of 'maximumPoolSize'.

Typically an application will like to use max threads and if all max threads are busy then queue task (in unbounded queue) instead of rejecting it. Application developers will know max concurrency possible on their environment hence they would set maximumPoolSize accordingly. But it will never be used in this case.

Can I get such behavior from ThreadPoolExecutor? I do not want to use bounded work queue.


The other question is on 'execute' method implementation
Following is the code snippet from the backport code

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        for (;;) {
            if (runState != RUNNING) {
                reject(command);
                return;
            }
            if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
                return;
            if (workQueue.offer(command))
                return;
            Runnable r = addIfUnderMaximumPoolSize(command);
            if (r == command)
                return;
            if (r == null) {
                reject(command);
                return;
            }
            // else retry
        }
    }


'addIfUnderMaximumPoolSize' is called only when the workQueue is FULL. It is called with 'command' as a parameter. Now lets look at 'addIfUnderMaximumPoolSize' method implementation as follows

    private Runnable addIfUnderMaximumPoolSize(Runnable firstTask) {
        Thread t = null;
        Runnable next = null;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (poolSize < maximumPoolSize) {
                next = (Runnable)workQueue.poll();
                if (next == null)
                    next = firstTask;
                t = addThread(next);
            }
        } finally {
            mainLock.unlock();
        }
        if (t == null)
            return null;
        t.start();
        return next;
    }

The method first polls the queue and as queue is FULL, it will read a runnable task from the queue. Hence next will never be null. In this case the method will never use 'firstTask' and it will return next which is a runnable from the queue.

Now back in the caller i.e. execute, r will never be same as command and it will never be null, hence no error is returned but 'command' task is neither in the queue nor as the first task of the new thread. There is a possibility that task 'command' is lost and is never executed.

Am I missing something here. Can someone help me understand this better? Prompt help would be appreciated.

Thanks,
Rahul

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@xxxxxxxxxxxxxxxxxxxx
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise