2016-04-24 10 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; 


} 

我觉得现在的问题是我定义线程对象 “ACQ”(在一个try catch块):

      // 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对象。如果你在那里得到一个空指针异常,那么它意味着acq == null。也请清理代码,因为它很难读取atm。 – mdewit

+0

除了你的NPE之外,我还会放下'stopped'变量(它必须是volatile) - 如果没有,它实际上会导致线程继续),并简单地使用中断状态,如http:// www中的清单5所示.ibm.com/developerWorks的/库/ J-jtp05236 / – zapl

回答

0

谢谢大家的宝贵意见,我解决了NullPointerException。问题在于acq对象的声明,它必须是静态的。现在线程正常工作。

1

其实有几个问题有:

1)你的代码格式是可怕的......至少使用一些IDE,做了intendation你。

2)你的班级命名不好。请遵守命名惯例。类名以“C”首字母开头。

3)最好不要使用方法名“interrupt()”。更糟的是,切勿在Thread/Runnable类中重写此方法!除非在那里调用super.interrupt()会导致严重的问题! 因为中断()正是让你的sleep()退出暂停状态的一件事情。

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(); 
    } 

}