[concurrency-interest] some questions with ThreadPoolExecutor

freish freish at 163.com
Tue Aug 14 20:16:55 EDT 2012


hi,all


I am reading the source code of ThreadPoolExecutor,I've found something interesting,but I am not sure whether it is reasonable or unreasonable.the detail is as bellow:


in class ThreadPoolExecutor$Worker's run method:


public void run() {
try {
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null) {
runTask(task);
task = null;
}
} finall y {
workerDone(this);
}
}


I find that if the current thread is going to die,most of the time no new thread is created to replace the dead one.The workerDone method source code:


void workerDone(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
if (--poolSize == 0)
tryTerminate();
} finally {
mainLock.unlock();
}
}


and tryTerminate:


private void tryTerminate() {
if (poolSize == 0) {
int state = runState;
if (state < STOP && !workQueue.isEmpty()) {
state = RUNNING; // disable termination check below
Thread t = addThread(null);
if (t != null)
t.start();
}
if (state == STOP || state == SHUTDOWN) {
runState = TERMINATED;
termination.signalAll();
terminated();
}
}
}


in the tryTerminate method,there is a new thread created in some condition.But in workerDone,only if the poolSize is 0 can the tryTerminate method be invoked.Then there is a scene:
if I have a thread pool with a unlimited BlockingQueue and corePoolSize equals 5,and I invoke the pool's execute method in a loop to submit 10 tasks. Each task will be executing for 5 seconds. but the first 5 tasks will be throw an RuntimeException after 5 seconds's execution.Then how many threads in the pool will execute the last 5 tasks?
as the code above,I guess only one. I've also writen some simple code to test th is:


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;


public class TestThreadPool {
private static final ExecutorService pool = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws InterruptedException {
for(int i=0; i<10; i++) {
pool.execute(new MyTask(i));
}
for(int i=0; i<40; i++) {
System.out.println(((ThreadPoolExecutor)pool).getPoolSize());
Thread.sleep(1 000L);
}
pool.shutdown();
}
static class MyTask implements Runnable {
private int num;
public MyTask(int index) {
this.num = index;
}
public void run() {
try {
Thread.sleep(5000L);
System.out.println("task " + num + " executed by " + Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
}
if(num < 5) {
throw new RuntimeExcepti on("task " + num + ",executed by " + Thread.currentThread());
}
}
}
}


Yes,the last five tasks are executed in only one thread.It seems like a bug of the class ThreadPoolExecutor,after all,it is a pool.Should we add a catch clause in the ThreadPoolExecutor$Worker's run method and do sth in it?
I am not sure whether there are some reasons for this behavor. 












Thank you


---------
Ticmy


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120815/f7f58d96/attachment.html>


More information about the Concurrency-interest mailing list