Pergunta

Eu tenho uma tarefa de longa duração, algo como:

public void myCancellableTask() {
    while ( someCondition ) {
       checkIfCancelRequested();
       doSomeWork();
    }
 }

A tarefa pode ser cancelado (a cancelar é solicitada e checkIfCancelRequested () verifica a bandeira cancelar). Geralmente quando eu escrevo laços canceláveis ??como este, eu usar uma bandeira para indicar que um cancelamento foi solicitado. Mas, eu sei que eu também poderia usar Thread.interrupt e verificar se o segmento foi interrompido. Eu não estou certo de que seria a abordagem preferida e por quê, pensamentos?

graças,

Jeff

Foi útil?

Solução

interrupção vai explodir o fio a partir de uma lista de condições de espera especificado. Seu próprio cancelar bandeira não vai. Se você quiser espera de interrupção no IO e eventos, utilize interrupção. Caso contrário, use o seu próprio.

Outras dicas

Um problema com o uso de interrupção é que se você não controlar todo o código que está sendo executado , você corre o risco da interrupção não trabalhando "corretamente" por causa de alguém está quebrado compreensão de como a interrupções punho em sua biblioteca. Essa é a API invisivelmente exportações uma API em torno de seu tratamento de interrupts que você se torna dependente.

No seu exemplo, doSomeWork suponha que estava em um JAR 3-parte e se parece com:

public void doSomeWork() {
    try { 
        api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); }
}

Agora você tem que lidar com um AssertionError (ou qualquer outra coisa que a biblioteca que você está usando pode lançar). Eu vi desenvolvedores experientes jogar todos os tipos de absurdo em receber interrupções! Por outro lado, talvez o método ficou assim:

public void doSomeWork() {
    while (true) {
        try { 
            return api.callAndWaitAnswer() ; 
        } 
        catch (InterruptedException e) { /* retry! */ }
    }
}

Esta "manipulação imprópria" de interrupção faz com que seu programa para repetir indefinidamente. Novamente, não descartar essa tão ridículo; há um monte de quebrada interrupção manipulação mecanismos lá fora.

Pelo menos usando sua própria bandeira será completamente invisível para quaisquer bibliotecas 3rd-party.

Depende da implementação doSomeWork(). É que a computação puro ou o faz (em qualquer ponto) envolvem bloqueio de API (como IO) chamadas? Por O bmargulies resposta, muitas APIs de bloqueio em JDK são interruptível e irá propagar a exceção interrompido até a pilha.

Assim, se o trabalho envolve potencialmente bloqueando atividades, você need'll tomar interrupções em consideração mesmo se você decide para controlar o processo de utilização de uma bandeira, e deve apropriadamente pegar e tratar / propagar a interrupções.

Além disso, se depender de uma bandeira, certificar-se de sua bandeira é declarado com a semântica volatile.

Eu acho que é uma questão de preferência na maioria dos casos. Pessoalmente eu gostaria de ir para a bandeira feitos à mão. Ele lhe dá mais controle - por exemplo, desta forma você certificar-se de que o seu segmento não deixar algum outro objeto em um estado inconsistente. Além disso, se o desempenho é realmente crítico, tenha em mente que o uso de exceções tem uma sobrecarga (mesmo que seja insignificante em 99% dos casos).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top