2012-12-19 7 views
4

Hey là, j'ai actuellement un problème avec mon application Android. Im commencer un fil supplémentaire via mise en œuvre du Excecutor Interface:Arrêter un exécutable dans un thread séparé

class Flasher implements Executor { 
    Thread t; 
    public void execute(Runnable r) { 
    t = new Thread(r){ 
    }; 
    t.start(); 
    } 
} 

Je commence mon Runnable comme ceci:

flasherThread.execute(flashRunnable); 

mais comment puis-je arrêter?

+0

http://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java –

+3

N'implémentez pas votre propre 'Executor' sans une très bonne raison de le faire - utilisez ceux déjà disponibles dans l'API Java. En outre: l'arrêt d'une tâche effectuée dans un autre thread dans Java repose toujours sur l'autre thread ou plutôt sur sa tâche de * coopérer *. Si votre Runnable reste assis dans une boucle sans fin, ne faisant rien, il n'y a pas moyen de l'arrêter. – JimmyB

+0

@ ρяσѕρєяK Il n'existe aucune méthode de ce type dans l'interface [Executor] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executor.html). – aymeric

Répondre

3

Vous ne savez pas si l'implémentation Executor est une bonne idée. Je préfère utiliser l'un des exécuteurs Java. Ils vous permettent de contrôler votre Runnable exemple via l'interface Future:

ExecutorService executorService = Executors.newSingleThreadExecutor(); 
Future<?> future = executorService.submit(flashRunnable); 
... 
future.cancel(true); 

Assurez-vous aussi ressources gratuites qui ExecutorService consomme en appelant executorService.shutdown() lorsque votre programme n'a pas besoin de l'exécution asynchrone plus.

+0

"vous permet de contrôler votre instance Runnable "- Désolé, mais ce n'est pas vrai.Ils vous permettent de contrôler le * 'Executor' *, mais le' Runnable' peut toujours faire ce qu'il veut, y compris ne pas terminer et donc déconner l'exécuteur et quoi d'autre. – JimmyB

+1

'future.cancel()' méthode peut retourner false, indiquant que votre demande d'annulation a échoué, mais 'Future' contrôle une seule instance' Runnable', pas le 'Executor' qui peut exécuter ou planifier des milliers de tâches – hoaz

+0

Alors, comment peut-on influencer l'instance 'Runnable' via le' Future'? – JimmyB

1

Au lieu d'implémenter votre propre Executor, vous devriez regarder ExecutorService. ExecutorService a une méthode d'arrêt qui:

Initie une fermeture ordonnée dans laquelle les tâches précédemment soumises sont exécutées, mais aucune nouvelle tâche ne sera acceptée.

5

Ok, ceci est juste le très filetage de base 101, mais nous allons être là un autre exemple:

filetage de la vieille école:

class MyTask implements Runnable { 
    public volatile boolean doTerminate; 

    public void run() { 
     while (! doTerminate) { 
      // do some work, like: 
      on(); 
      Thread.sleep(1000); 
      off(); 
      Thread.sleep(1000); 
     } 
    } 
} 

puis

MyTask task = new MyTask(); 

Thread thread = new Thread(task); 

thread.start(); 

// let task run for a while... 

task.doTerminate = true; 

// wait for task/thread to terminate: 
thread.join(); 
// task and thread finished executing 

Edit:

Juste trébuché sur cette très infor mative Article sur la façon d'arrêter les threads.

+1

La manière standard de Java d'interrompre un thread est ... d'interrompre le thread. Et dans votre Runnable, vous pouvez utiliser 'while (! Thread.currentThread(). IsInterrupted()) {soSomething();}' pour arrêter ce que vous faites lorsqu'un signal d'interruption est envoyé. – assylias

+1

Sans aucun doute. - Cependant, il existe toujours * no * moyen de forcer arbitrairement 'Runnable' (ou thread) à se terminer; dans * chaque * cas, la coopération avec le 'Runnable 'est requise. Et c'est le point de l'OP: Pour être en mesure d'arrêter un thread en cours d'exécution, le code dans ce thread doit être explicitement écrit pour soutenir cela. – JimmyB

+0

Je ne suis pas en train de discuter sur le bit de coopération - juste dire que la coopération est généralement mise en œuvre avec le mécanisme d'interruption plutôt que des drapeaux booléens. – assylias

1

Je suggère d'utiliser le ExecutorService, avec l'objet Furure, qui vous donne le contrôle sur le thread qui est créé par l'exécuteur. Comme dans l'exemple suivant

ExecutorService executor = Executors.newSingleThreadExecutor(); 
Future future = executor.submit(runnabale); 
try { 
    future.get(2, TimeUnit.SECONDS); 
} catch (TimeoutException ex) { 
    Log.warn("Time out expired"); 
} finally { 
    if(!future.isDone()&&(!future.isCancelled())) 
     future.cancel(true); 

    executor.shutdownNow(); 
} 

Ce code indique que le runnable sera forcé de se terminer après 2 secondes. Bien sûr, vous pouvez gérer votre futur objet comme vous le souhaitez et le terminer en fonction de vos exigences

Questions connexes