Quando uma thread termina um Runnable, ela não pode reiniciar a execução, com um novo Runnable. Seria necessário criar outra thread, que é justamente o que o seu pool quer evitar.
Portanto, você deve criar um outro Runnable, que gerencie isso para você. Esse runnable não terminaria. Ele receberia uma task, a executaria, e então aguardaria uma nova Task.
Seria algo mais ou menos assim:
[code]
public PoolRunner implements Runnable {
public Runnable aRunnable = null;
public void setRunnable(Runnable runnable) {
if (aRunnable != null)
throw new IllegalArgumentException(“There’s already a task running on this thread!”);
if (runnable == null)
throw new IllegalArgumentException(“Cannot submit a null task!”);
this.aRunnable = runnable;
//Vamos avisar o nosso método run() de que temos trabalho a fazer.
notify();
}
private synchronized void waitTask() {
//Precisamos do while para evitar o spurious wakeup
while (!hasTask())
wait();
}
public void hasTask() {
return aRunnable != null;
}
public void run() {
try {
//Se formos interrompidos, abandonamos a thread.
//Assim vc usa o interrupt para “matar” o Pool.
while (!Thread.interrupted()) {
//Esperamos uma Task para o processamento
waitTask();
//Processamos essa task.
aRunnable.run();
//E limpamos a variável para na próxima iteração
//esperarmos novamente.
aRunnable = null;
}
catch (InterruptedException e) {
}
}
}[/code]
Cada thread do seu pool irá ter como Runnable instâncias desse cara. Note que essa instância controlará um outro Runnable, sua Task, que será submetida ao Pool.
Note que, apesar da sua task executar inteira, após o seu termino esse runnable voltará a chamar o wait() e manterá a thread dormindo até que outra task seja submetida a ele.
Você ainda pode adicionar a essa classe um mecanismo para notificar o Pool de threads ao qual ela pertence de que a task em execução terminou de executar.