2016-04-24 18 views
0

私は、開始ボタンと停止ボタンがある単純なJava GUIを持っています。スレッドを開始するにはスタートボタンを使用し、スレッドを停止するには停止ボタンを使用します。スレッドはうまく始まりますが、停止ボタンで止めることはできません。ここに私のコードの一部は次のとおりです。Javaスレッドを取得して停止させることはできません

これは、グラフィックインタフェースのためのクラスです:

public class GridController implements ActionListener { 
// Definisco la vista 
private final GridView vista; 

acqreg acq; 
public GridController(final GridView vista) { 
    this.vista = vista; 

} 

@Override 
public void actionPerformed(final ActionEvent e) { 
    Object src = e.getSource(); 
    String ID = null; 
    String IP = null; 



    if (src == this.vista.startacqButton) {  

     // Reset di tutte le Label di errore 
     this.resetLabels(); 

     // Check degli input sui campi 
     if (this.checkAllInputs()) { 
      // CONTROLLO CAMPI ANDATO A BUON FINE 
      System.out.println("Campi Compilati Correttamente"); 

      // Inibisco le pressioni successive del bottone start 
      this.vista.startacqButton.setEnabled(false); 
      // Inibisco la modifica dei campi inseriti sul form 
      this.vista.getcbIDphidget().setEnabled(false); 
      this.vista.gettfMiscela().setEnabled(false); 
      this.vista.gettfLotto().setEnabled(false); 
      this.vista.gettfDataop().setEnabled(false); 
      // Riattivo lo stop button 
      this.vista.stopacqButton.setEnabled(true); 

      // POSSO FAR PARTIRE L'ACQUISIZIONE ----------------------------------------------------------------------------------------------------------------- 

      try { 

       // Recupero la coppia ID Scheda - IP Scheda dal file conf 
       BufferedReader phidgetip = new BufferedReader(new FileReader("PhidgetsIP.conf")); 
       String riga; 
       while ((riga = phidgetip.readLine()) != null){ 
        String[] parts = riga.split("#"); 
        String part1 = parts[0]; // ID Phidget 
        String part2 = parts[1]; // IP Phidget 


         if (part1.equals(this.vista.cbIDphidget.getSelectedItem())) { 
          ID = part1; 
          IP = part2; 


          // Creo oggetto per l'acquisizione 
          acq = new acqreg(ID , IP , vista); 
          //Avvio il thread 
          acq.start(); 

          } 

       } 
      } catch (FileNotFoundException ex) { 
       Logger.getLogger(GridController.class.getName()).log(Level.SEVERE, null, ex); 
      } catch (IOException ex) { 
       Logger.getLogger(GridController.class.getName()).log(Level.SEVERE, null, ex); 
      } 

      // Ho trovato l'ID giusto --> apro il canale di comunicazione 



     }else{ 
      System.out.println("Alcuni campi non sono stati compilati correttamente"); 
       } 


    }else if(src == this.vista.stopacqButton){ 

      // Inibisco le pressioni successive del bottone stop 
      this.vista.stopacqButton.setEnabled(false); 
      // Riattivo lo start button 
      this.vista.startacqButton.setEnabled(true); 
      // Inibisco la modifica dei campi inseriti sul form 
      this.vista.getcbIDphidget().setEnabled(true); 
      this.vista.gettfMiscela().setEnabled(true); 
      this.vista.gettfLotto().setEnabled(true); 
      this.vista.gettfDataop().setEnabled(true); 
      // Stoppo l'acquisizione 

      acq.interrupt(); 
    }                        
    } 

}

...これはスレッド「ACQ」を実行したクラスです。

public class acqreg extends Thread { 

private final String ID; 
private final String IP; 
private final GridView vista; 



public acqreg(String ID , String IP, GridView vista){ 
    this.IP=IP; 
    this.ID = ID; 
    this.vista=vista; 

} 



public void run() { 



    stopped=false; 


     try{ 

      //.....do something..... 




      //dichiarazione variabili di acquisizione 
      final long start = System.nanoTime();  
      int seriale; 
      double tempDevice; 
      double tempAmbiente; 
      long prg = 1; 

        //Ciclo di acquisizione 
        while (!stopped) { 

        // ....do the long work.... 

        Thread.sleep(1000); 




        } 

    } 
     }catch(Exception ex){ 



     } 
} 

@Override 
public void interrupt() { 


stopped=true; 


} 

私は(トライcatchブロック内)スレッドオブジェクト「ACQ」を定義するところに問題があると思う:

      // Creo oggetto per l'acquisizione 
          acq = new acqreg(ID , IP , vista); 
          //Avvio il thread 
          acq.start(); 

私はスレッドを停止しようとするので:

else if(src == this.vista.stopacqButton){ 

     .......some code......... 

     // Stoppo l'acquisizione 

     acq.interrupt(); 

interrupt()メソッドは起動せず、スレッドは実行を継続します。デバッグモードでは、このエラーが "acq.interrupt()"という行にあります。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 

私を助けてください。すべてに大きなおかげで!

+1

acqオブジェクトが割り当てられていることを確認してください。そこにnullpointer例外がある場合、それはacq == nullを意味します。また、atmを読むのが非常に難しいので、コードを少しきれいにしてください。 – mdewit

+0

あなたのNPEに加えて、私は 'stopped'変数(' volatile'が必要 - 実際にスレッドを続行させる必要がある)を落とし、http:// wwwのリスト5のような割り込みステータスを使います.ibm.com/developerworks/library/j-jtp05236 / – zapl

答えて

0

貴重なコメントをいただき、ありがとうございます。NullPointerExceptionを解決しました。問題は、STATICでなければならないacqオブジェクトの宣言にありました。今すぐスレッドが正常に動作します。

1

は、実際にそこにいくつかの問題があります。

1)あなたのコードのフォーマットは、少なくともあなたのためintendationを行い、いくつかのIDEを使用して...恐ろしいです。

2)あなたのクラスの命名は悪いです。命名規則に従ってください。クラス名は "C"の頭文字で始まります。

3)メソッド名 "interrupt()"を使用しない方が良い。さらに悪いことに、このメソッドをThread/Runnableクラスでオーバーライドしないでください!そこにsuper.interrupt()を呼び出さない限り、重大な問題が発生します! interrupt()はあなたのsleep()を中止することができる1つのものです。

4)少なくとも何らかの基本的な例外処理を行います。何をしているのか正確に分からない限り、例外を無視してはいけません。

これは、やや上品なワーカースレッドのようなものです。すべてのスレッド関連の処理を呼び出し元から取り除き、startThread()メソッドとstopThread()メソッドにのみアクセスを許可します。このようにして、外部から不正に干渉することはありません。

/** 
* This worker can only run once 
* @author JayC667 
*/ 
public class ProperThreading { 

    private final Thread  mThread   = new Thread(() -> runWorkingLoop()); // if you want worker to be able to run multiple times, move initialisation into startThread() 
    private volatile boolean mThreadStarted = false; 
    private volatile boolean mStopRequested = false; 

    private final long   mLoopSleepTime; 

    public ProperThreading(final long pLoopSleepTime /* pass more arguments here, store in members */) { 
     mLoopSleepTime = pLoopSleepTime; 
    } 

    public synchronized void startThread() { 
     if (mThreadStarted) throw new IllegalStateException("Worker Thread may only be started once and is already running!"); 
     mThreadStarted = true; 
     mThread.start(); 
    } 

    private void runWorkingLoop() { 
     while (!mStopRequested /* && other checks */) { 
      try { 
       // do the magic work here 
       Thread.sleep(mLoopSleepTime); 

      } catch (final InterruptedException e) { 
       break; 
      } catch (final Exception e) { 
       // do at least some basic handling here, you should NEVER ignore exception unless you know exactly what you're doing, and then it should be commented! 
      } 
     } 
    } 

    public synchronized void stopThread() { 
     if (!mThreadStarted) throw new IllegalStateException("Worker Thread is not even running yet!"); 
     mStopRequested = true; 
     mThread.interrupt(); 
    } 

} 
関連する問題