2010-07-05 6 views
4

Nous avons besoin d'un morceau de code pour contrôler un fil. Par exemple, utilisez trois boutons comme démarrer, arrêter et mettre en pause, appuyez sur l'un d'eux et effectuez l'action contre. Comme appuyez sur start, puis démarrer le fil, appuyez sur stop arrête réellement le fil et pause effectuer une action de pause respectivement.Fil de contrôle par le bouton

+0

double possible de [démarrer et arrêter le contrôle de fil par bouton] (http://stackoverflow.com/questions/3178129/start-and-stop-thread-control- via le bouton) –

Répondre

4

Le démarrage d'un thread est simple avec Thread.start(). L'arrêt d'un thread peut être aussi simple que de définir un indicateur vérifié de manière asynchrone dans la méthode run, mais peut nécessiter un appel à Thread.interrupt(). La mise en pause d'un thread est plus problématique, mais peut également être effectuée à l'aide d'un indicateur qui permet à la méthode run de céder au lieu de processus. Voici le code (non testé):

class MyThread extends Thread { 
    private final static int STATE_RUN = 0, STATE_PAUSE = 2, STATE_STOP = 3; 
    private int _state; 

    MyThread() { 
     _state = STATE_RUN; 
    } 

    public void run() { 
     int stateTemp; 

     synchronized(this) { 
      stateTemp = _state; 
     } 

     while (stateTemp != STATE_STOP) { 
      switch (stateTemp) { 
       case STATE_RUN: 
        // perform processing 
        break; 
       case STATE_PAUSE: 
        yield(); 
        break; 
      } 
      synchronized(this) { 
       stateTemp = _state; 
      } 
     } 
     // cleanup 
    } 

    public synchronized void stop() { 
     _state = STATE_STOP; 
     // may need to call interrupt() if the processing calls blocking methods. 
    } 

    public synchronized void pause() { 
     _state = STATE_PAUSE; 
     // may need to call interrupt() if the processing calls blocking methods. 
     // perhaps set priority very low with setPriority(MIN_PRIORITY); 
    } 

    public synchronized void unpause() { 
     _state = STATE_RUN; 
     // perhaps restore priority with setPriority(somePriority); 
     // may need to re-establish any blocked calls interrupted by pause() 
    } 
} 

Comme vous pouvez le voir, il peut obtenir assez rapidement complexe en fonction de ce que vous faites dans le fil.

+1

Il serait probablement préférable d'utiliser 'this.wait()' au lieu de 'yield()', et d'ajouter 'this.notify()' à 'unpause()' et 'stop()' . –

2

Je voudrais ajouter la réponse de Richard pour répondre à quelques questions:

  1. cycles Inutile en pause
  2. cycle extra Inutile lorsque l'état a changé
  3. yield() utilisé où wait() nécessaire
  4. instance unique
  5. L'arrêt du fil attend que le fil se termine

C'est mon code modifié:

class MyThread extends Thread { 
    private final static int STATE_RUN = 0, STATE_PAUSE = 2, STATE_STOP = 3; 
    private int _state; 

    private static MyThread thread; 

    public static MyThread getInstance() { 
     if (thread == null || !thread.isAlive()) { 
      thread = new MyThread(); 
     } 
     return thread; 
    } 


    private MyThread() { 
     _state = STATE_RUN; 
    } 

    public static void main(String[] args) { 
     MyThread t = MyThread.getInstance(); 
     try { 
      t.start(); 
      Thread.sleep(500); 
      t.pause(); 
      Thread.sleep(500); 
      t.unpause(); 
      Thread.sleep(500); 
      t.end(); 
     } catch (InterruptedException e) { 
      // ignore; this is just an example 
     } 
    } 

    public void run() { 
     int i = 0; 
     while (_state != STATE_STOP) { 
      if (_state == STATE_PAUSE) { 
       System.out.println(this + " paused"); 
       synchronized (this) { 
        try { 
         this.wait(); 
        } catch (InterruptedException e) { 
        } 
       } 
      } 
      if (_state == STATE_STOP) { 
       break; 
      } 

      // this is where the actual processing happens 
      try { 
       // slow output down for this example 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       // state change handled next cycle 
      } 

      System.out.println(this + " cycle " + i); 
      i++; 
     } 
     System.out.println(this + " finished"); 
     // cleanup 
    } 

    public synchronized void end() { 
     _state = STATE_STOP; 
     try { 
      this.interrupt(); 
      this.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    public synchronized void pause() { 
     _state = STATE_PAUSE; 
    } 

    public synchronized void unpause() { 
     _state = STATE_RUN; 
     synchronized (this) { 
      this.notify(); 
     } 
    } 
} 
Questions connexes