gpt4 book ai didi

java - 无法检索 Java 线程来停止它

转载 作者:行者123 更新时间:2023-12-01 10:00:52 24 4
gpt4 key购买 nike

我有一个简单的 Java GUI,带有启动和停止按钮。我使用启动按钮来运行线程,使用停止按钮来停止它。线程启动正常,但我无法用停止按钮停止它。这是我的一段代码:

这是图形界面的类:

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 block 中):

                           // 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()方法没有启动,线程继续运行!在 Debug模式下,我在“acq.interrupt()”行出现此错误:

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

最佳答案

实际上有几个问题:

1) 你的代码格式太糟糕了...至少使用一些可以满足你要求的 IDE。

2)你的类命名不好。请遵守命名约定。类名以“C”大写字母开头。

3) 最好不要使用方法名称“interrupt()”。更糟糕的是,永远不要在 Thread/Runnable 类中重写此方法!除非在那里调用 super.interrupt() 这会导致严重的问题!因为 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();
}

}

关于java - 无法检索 Java 线程来停止它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36822222/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com