Comment tuer tous les threads d'une liste

Fermé
GregNoob - 31 janv. 2014 à 16:38
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 - 1 févr. 2014 à 00:01
Bonjour,

j'ai un petit souci lorsque je veux tuer l'ensemble des threads d'une même liste...

en fait j'ai plusieures listes de threads pour extraire des données à différents endroits :



private List<ExtractionThread> threadList1 = new ArrayList<ExtractionThread>();
private List<ExtractionThread> threadList2 = new ArrayList<ExtractionThread>();
private List<ExtractionThread> threadList3 = new ArrayList<ExtractionThread>();

Quand un de mes threads se termine, il fait une notification qui appelle une méthode qui tue l'ensemble des threads de cette liste (car dès que j'ai un match, je veux killer tout):
<code>
private void KillthreadList(List<ExtractionThread> threadList) {
System.out.println("Taille de ma threadList : "+threadList.size());
for(int i = threadList.size()-1;i>=0;i--){
System.out.println("Killing Thred n°"+threadList.get(i).getId());
threadList.get(i).stop();
}
}

Le pb se situe quand 2 listes de threads notifient quasiement en même temps et donc appellent cette méthode KillThreadList.
Il me reste des threads vivants...

Ex quand je lance :
Taille de ma threadList : 10
Killing Thred n°44
Killing Thred n°43
Killing Thred n°42
Killing Thred n°41
Taille de ma threadList : 5
Killing Thred n°57
Killing Thred n°56
Killing Thred n°55
Taille de ma threadList : 4
Killing Thred n°20
Killing Thred n°19
Killing Thred n°18
Killing Thred n°17


Merci par avance de votre aide
Cordialement,
Le noob
A voir également:

1 réponse

KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
31 janv. 2014 à 20:53
Il faudrait synchroniser ta méthode killThreadList sur ta liste pour qu'un seul de ces thread puisse rentrer dedans à la fois.

Remarque : la méthode stop() est dépréciée car dans certain cas elle plante, il faut en remplacement utiliser la méthode interrupt() et gérer dans tes thread l'état isInterrupted().

Exemple :

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class Test
{   
    public static class ExtractionThread extends Thread
    {
        private static final Random rand = new Random();
        private static final AtomicInteger ids = new AtomicInteger(0);
        private final int id = ids.incrementAndGet();
        private final List<Thread> group;
        
        public ExtractionThread(List<Thread> group)
        {
            this.group = group;
        }
        
        @Override
        public void run()
        {
            int nb = rand.nextInt(100);
            System.out.println(this+" start for "+nb+" loop");
            
            for (int i=0; i<nb; i++)
            {
                if (isInterrupted())
                {
                    System.out.println(this+" is interrupted");
                    return;
                }
                
                System.out.println(this+" at step "+i+"/"+nb);
            }
            
            System.out.println(this+" ends at "+nb);
            
            interruptAllGroupThread();
        }

        public void interruptAllGroupThread()
        {
            synchronized(group)
            {
                setPriority(MAX_PRIORITY);
                
                System.out.println(this + " interrupt all : "+group);
                
                // Send interrupt call
                for (Thread t : group)
                {
                    if (t==this)
                        continue;
                    
                    System.out.println("Thread " + id + " interrupt : "+t);
                    t.interrupt();
                }
                
                // Wait all thread ends
                for (Thread t : group)
                {
                    if (t==this)
                        continue;
                    
                    try
                    {
                        t.join();
                    }
                    catch (InterruptedException e)
                    {
                        System.err.println("Can't wait "+t);
                    }
                }

                System.out.println(this+" have interrupt all");
            }
        }
        
        @Override
        public String toString()
        {
            return "T"+id;
        }
    }

    public static void main(String[] args) throws IOException
    {
        int n = 10;
        List<Thread> group = new ArrayList<Thread>(n);

        for (int i=0; i<10; i++)
            group.add(new ExtractionThread(group));
        
        for (Thread t : group)
            t.start();
    }
}
0
GregNoob Messages postés 1 Date d'inscription vendredi 31 janvier 2014 Statut Membre Dernière intervention 31 janvier 2014
31 janv. 2014 à 23:27
Bonjour,

merci pour ta réponse claire et rapide.

Le problème est que le plus gros de mon thread tiens dans une ligne (comparatif d'images avec sikuli, je n'ai pas accès au code natif qui est en C) et que je voudrais vraiment tuer mon thread tout de suite (pendant qu'il est en train d'effectuer le traitement de cette ligne, et non pas juste après....

de plus, j'ai essayer de mettre un synchronized sur ma méthode de KillThreadList mais ça donne toujours le même résultat...
Normalement, si je fais :

private synchronized void KillthreadList(List<ExtractionThread> threadList) {
//Kill My threads
}

cette méthode ne devrait pas pouvoir être rappelée par un thread ou autre tant qu'elle n'a pas fini son traitement c'est bien ça ?

Merci par avance de ton éclaircissement
Cordialement
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
1 févr. 2014 à 00:01
En faisant un synchronized sur la méthode, l'élément de synchronisation c'est this, or chacun a le sien, il n'y a donc pas le comportement que tu as attends. C'est pour cela que j'ai fait le synchronized sur la liste qui elle est bien commune à tous les thread.

La méthode ne pourra donc pas être appelé par un autre thread s'il "s'identifie" avec la même liste.
0