Eu tenho um ThreadPool no meu aplicativo Android, onde eu corro um monte de threads em diferentes situações nele.
public class ThreadPoolExecuter {
private final ExecutorService mExecuter;
private static final int nThreads = 5;
private ThreadPoolExecuter() {
this.mExecuter = Executors.newFixedThreadPool(nThreads);
}
O Java ThreadPool não tem padrão para cancelar o encadeamento. Uma solução em que pensei foi em manter um par de valores-chave do futuro quando envio um executável.
public void add(Runnable runnable) {
Future<?> future = this.mExecuter.submit(runnable);
// Add future to my key-value pairs
if(Constant.DEBUG) Log.d(TAG, "Task submitted.");
}
E então tenha uma função de cancelamento:
public boolean cancel(KEY) {
Future<?> future = map.get(KEY)
return future.cancel(mayInterruptIfRunning);
}
Digamos um HashMap. O valor é o Futuro, e a chave? 1) Qual é a sua sugestão?
Map<Key, Future<?>> map = new HashMap()<key, Future<?>>;
Sobre a chave, pensei em passar um ID para cada executável da seguinte maneira:
2) o que você acha dessa solução?
Mas eu mencionaria que, na minha classe executável, às vezes me deparei com o InterruptedException. Existe alguma maneira de evitá-lo?
class Runner implements Runnable {
private int id;
public Runner(int id) {
this.id = id;
}
@Override
public void run() {
System.out.println("Starting " + id);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Crashed on:" + Thread.currentThread().getId());
}
System.out.println("ending " + id);
}
}
3) No final, quero acrescentar que é importante que eu conheça alguma solução melhor no seu ponto de vista para desenvolver uma função de cancelamento no java ThreadPool?
Observe que não procuro um substituto para o meu ThreadPool, como o AsyncTask no Android, que possui o cancelamento padrão.
Respostas:
1 para resposta № 1Como sua principal necessidade é poder cancelar todas as tarefas em execução ao mesmo tempo, você poderá usar shutdownNow()
do ExecutorService
. Padrão ExecutorService
implementações chamará Thread.interrupt()
para abortar os threads em execução, então você deve lidar com InterrputedException
corretamente (fechando todos os recursos utilizados e saindo do encadeamento).
0 para resposta № 2
Geralmente cancelando threads de fora doo próprio encadeamento contém todos os tipos de riscos que não são óbvios a princípio. Uma abordagem mais segura é fazer com que o encadeamento, quando ele começa, verifique se ainda precisa ser executado.