3 votes

Comment arrêter une tâche après qu'elle ait expiré x fois ?

J'essaie d'exécuter un runnable plusieurs fois, et s'il ne se termine pas dans les x secondes 3 fois, je l'annule.

Le code que j'utilise pour simuler la situation où la tâche doit être annulée est le suivant. D'après la sortie, je peux voir qu'une InterruptedException a été levée et attrapée en conséquence, mais la tâche continue de fonctionner.

Il semble que les deux premières fois que la tâche a été exécutée avant que l'exception TimeoutException ne soit levée 3 fois, ces deux exécutions ont continué à fonctionner jusqu'à ce qu'elles soient terminées. Je me demande s'il existe un moyen d'empêcher ces deux exécutions de se terminer ?

public class SomeClass {

private static int c =0;

public static void main(String[] args){
    Runnable dummyRunnable = new Runnable() {

        @Override
        public void run() {
            System.out.println("Hello from dummyRunnable!");        

                for (int i =0; i< 10; i++){
                    try {
                        //simulate work here
                        if (!Thread.currentThread().isInterrupted()) Thread.sleep(5000);
                        System.out.println("thread sleeps for the " + i + " time!");    
                    } catch (InterruptedException ie){
                        System.out.println("InterruptedException catched in dummyRunnable!");   
                        //Thread.currentThread().interrupt(); //this has no effects
                        break;

                    }
                }

        }
    }; 

    BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(10 * 3, true);
    ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, Long.MAX_VALUE, TimeUnit.MILLISECONDS, blockingQueue);

    for (int i =0; i< 5; i++){
        Future<?> task = executor.submit(dummyRunnable);

        try{
            Thread.sleep(1000);
            task.get(2000, TimeUnit.MILLISECONDS);
        } catch (TimeoutException te){
            c++;
            System.out.println("TimeoutException from a task!");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (c==3){
                System.out.println("cancelling task...");
                task.cancel(true);
                break;
            }
        }
    }
     }
}

0voto

user2079185 Points 15

Je ne comprends pas ce que vous essayez réellement de simuler. Je m'attendrais à une simulation comme le paiement par carte (60 secondes de temps mort pour terminer une tâche) ou peut-être une secrétaire dans une situation médecin-patient.

Dans l'état actuel des choses, vous créez les 5 objets dans le futur. Si vous voulez avoir plus de contrôle sur vos threads, vous devriez penser à utiliser des méthodes synchronisées et un moniteur qui gère les threads pour vous.

En général, lorsque vous commencez un fil de discussion, vous devez choisir

new Thread(new Task(object or generics)).start();
Thread.sleep(2000); // calls this thread to wait 2 secs before doing other task(s)

Avant de faire de la concurrence pure et dure (multithreading), vous devriez lire quelques tutoriels Java pour vous inspirer... http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X