Partage
  • Partager sur Facebook
  • Partager sur Twitter

JAVA/Swing : Mettre en pause et relance une thread

Le faire a partir d'une autre thread

Sujet résolu
    27 avril 2016 à 20:09:27

    Bonjour,

    Pour un TP en cours, on doit utiliser les ReentrantLock pour mettre en pose un thread et la relancer en appuyant sur un bouton (JToggleButton).
    Le thread a mettre en pause et a relancer et fait grâce a une classe qui hérite de SwingWorker .

    Le but est de simuler un programme de téléchargement qui permet de mettre en pause et relancer ses DL au besoin.

    Je n'arrive pas a le faire, quand je presse le bouton j'arrive bien a lancer mes fonction pour locker et delocker simplement je n'arrive pas a faire en sorte que ces fonctions agisse sur le thread a mettre en pause.

    J'ai essayer deux méthode :

    - Quand on appuie sur le bouton, appliquer directement lock.lock() mais sa ne bloque pas la thread voulut

    - Quand on appuie sur le bouton, une boolean est changer, boolean qui est utiliser dans la thread voulut dans sa boucle d’exécution pour vérifier si elle doit se lock ou pas, ce qui marche pour la bloquer, mais après impossible de la relancer

    Je voit vraiment pas quoi faire :/ 

    Voici le code principal (je vous épargne celui de l'interface elle marche bien ^^ )

    public class Downloader extends SwingWorker {
    
        public static final int CHUNK_SIZE = 1024;
    
        URL url;
        int content_length;
        BufferedInputStream in;
    
        String filename;
        File temp;
        FileOutputStream out;
    
        private int _progress;
        private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    
        private ReentrantLock lock = new ReentrantLock();
        private boolean isLocked;
    
        public Downloader(String uri) {
            this.isLocked = false;
    
            try {
                url = new URL(uri);
    
                URLConnection connection = url.openConnection();
                content_length = connection.getContentLength();
    
                in = new BufferedInputStream(connection.getInputStream());
    
                String[] path = url.getFile().split("/");
                filename = path[path.length - 1];
                temp = File.createTempFile(filename, ".part");
                out = new FileOutputStream(temp);
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public String toString() {
            return url.toString();
        }
    
        @Override
        protected Object doInBackground() throws Exception {
    
            byte buffer[] = new byte[CHUNK_SIZE];
            int size = 0;
            int count = 0;
    
            while (count >= 0) {
                try {
                    out.write(buffer, 0, count);
                } catch (IOException e) {
                    continue;
                }
    
                size += count;
                setProgress(100 * size / content_length);
                Thread.sleep(1000);
    
                //Verifier si le DL doit se mettre en pause ou non
                if(isLocked){
                    lock.lock();
                }else{
                    lock.unlock();
                }
                
    
    
          
                try {
                    count = in.read(buffer, 0, CHUNK_SIZE);
                } catch (IOException e) {
                    continue;
                }
            }
    
            if (size < content_length) {
                temp.delete();
                throw new InterruptedException();
            }
    
            temp.renameTo(new File(filename));
            return filename;
        }
    
        public void lock() {
            isLocked = true;
            System.out.println("fonction lock");
        }
    
        public void unlock() {
            isLocked = false;
            System.out.println("fonction unlock");
        }
    
    }



    -
    Edité par Phentom 27 avril 2016 à 20:34:45

    • Partager sur Facebook
    • Partager sur Twitter
      27 avril 2016 à 21:09:25

      Un Thread va se mettre en pause quand tu va lui demander d'accéder à un objet qui est verrouillé (lock). Il va attendre qu'il soit libéré.

      • Partager sur Facebook
      • Partager sur Twitter
        27 avril 2016 à 21:22:55

        Je ne voit pas du tout comment je suis sensé demende a mon thread d'acceder a un objet verouillé :/

        (Si tu peut donner un exemple simple de code j'aimerai bien, meme si il se passe rien dans le thread a bloquer j'aimerais voir ce que tu entend par ta phrase, defois que j'arrive a appliquer le code au mien ^^)

        -
        Edité par Phentom 27 avril 2016 à 21:50:09

        • Partager sur Facebook
        • Partager sur Twitter
          28 avril 2016 à 8:42:13

          Ou sinon utiliser un booléen pour définir si le thread est en cours ou pas, et le tester dans ta boucle :

          Pseudo code :

          private boolean stoped;
          private int cpt;
          
          void method() {
              while (!stoped && cpt++ < 42) {
                  doSomething();
              }
          }
          
          void start() { method(); }
          
          void stop() { stoped = true; }
          
          void resume() { method(); }
          • Partager sur Facebook
          • Partager sur Twitter
          Angular 2 est l'avenir, jQuery c'est de la merde !!! - Java 8 c'est l'an 2016+ (programmez en 1 ligne)
            28 avril 2016 à 13:45:07

            Merci pour l'idée, mais pas sur que ca marche, en effet le but et de reprendre le dl a l'endroit ou il était, si je stoppe la boucle je ne peut pas la relancer car elle est dans la méthode doInBackground hérité de SwingWorker qui ne peut etre lancer qu'une seule fois (on ne peut pas rappeler plusieur fois cette fonction :/)

            Et puis dans le tp il demande clairement d'utiliser le systéme de Lock() simplement c'est la dernier question (un peu en mode exploration) et donc on a pas eu de cours sur ce type de fonction et on doit se debrouiller avec la dock et la bah j'y arrive pas XD
            • Partager sur Facebook
            • Partager sur Twitter
              28 avril 2016 à 14:09:48

              J'ai réussis !!!! En allant jeter un œil au code source du ReentrantLock j'ai compris comment il marcher, je post ici la solution que je vais commenter si jamais un jour quelqu'un en a besoin :

              Dans le thread que je souhaite bloquer, dans la boucle j'ai juste ajouter :

              lock.lock()
              lock.unlock()

              Et mon bouton active celons son état (mettre en pause ou relancer) les fonctions suivantes :

                  public void lock() {
                      lock.lock();
                  }
              
                  public void unlock() {
                      lock.unlock();
                  }


              Enfaîte le mécanisme des lock est super simple, la fonction lock() essaye d'attribuer l'objet (ici lock) au thread, si il est libre il le prend. Si il est déjà tenu par une autre thread, il attend qu'il se libère et se l'approprie.

              Donc mon thread de download s'approprie et relâche le lock en continue, et quand j'appuie sur le bouton pause c'est le bouton qui s'approprie le lock ce qui fait que quand la boucle va essayer d'y accéder, elle sera bloquer jusqu’à que lock soit liberer.

              Donc quand je reappuie sur le bouton, le lock est libéré la boucle de DL le récupére et le relibère et continue jusqu’à que je la rebloque

              Je ne sais pas si c'est claire, en tous cas je suis content d'y être arriver :)

              -
              Edité par Phentom 28 avril 2016 à 14:11:49

              • Partager sur Facebook
              • Partager sur Twitter
                28 avril 2016 à 14:19:19

                tokazio a écrit:

                Un Thread va se mettre en pause quand tu va lui demander d'accéder à un objet qui est verrouillé (lock). Il va attendre qu'il soit libéré.


                Voilà :)
                • Partager sur Facebook
                • Partager sur Twitter
                  28 avril 2016 à 15:22:33

                  Ouai mais j'avais pas compris ce que tu entendais par la ^^ (enfin ca ma aider aussi quand j'ai lut la doc a comprend pour me debloquer, merci bien du coups de main :) )
                  • Partager sur Facebook
                  • Partager sur Twitter

                  JAVA/Swing : Mettre en pause et relance une thread

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown