I have a GUI with a 'process' button. When the button is pressed, the following code is executed:
//Check for results truncation
boolean truncate = !jCheckBoxTruncate.isSelected();
String[] args = {fileName};
//run solution and draw graph
SpeciesSelection specSel = new SpeciesSelection(args, truncate);
Thread t = new Thread(specSel);
t.start();
long startTime = System.nanoTime();
cancelled = false;
jButtonCancel.setVisible(true);
new Thread() {
@Override
public void run() {
while (!specSel.isFinished() && !cancelled) {
double seconds = (System.nanoTime() - startTime) / 1000000000.0;
jLabelProcessTime.setText("Processing Time: " + toTimeString(seconds));
try {
Thread.sleep(91);
} catch (InterruptedException ex) {
Logger.getLogger(SpecSelGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
jButtonCancel.setVisible(false);
jButtonProcess.setEnabled(true);
// If processing finished then display result graph, else the process was cancelled so stop the processing thread.
if (specSel.isFinished()) {
ArrayList<Double> result = specSel.getResult();
drawGraph(result);
}
else {
t.interrupt();
}
}
}.start();
So I have a 'Thread t' that executes a long running process, and an anonymous thread that just updates the processing time on the GUI and monitors for a request to cancel Thread t. The SpeciesSelection class overrides run() as follows:
@Override
public void run() {
long start = System.nanoTime();
try {
result = specSel(args, truncate);//VERY LONG RUNNING PROCESS CALLED ONCE
} catch (FileNotFoundException ex) {
Logger.getLogger(SpeciesSelection.class.getName()).log(Level.SEVERE, null, ex);
}
finished = true;
System.out.println("Process took " + ((System.nanoTime() - start) / 1000000.0) + "ms");
}
I have a cancel button that sets the flag 'cancelled' to true. In the event that this button is pressed I attempt to interrupt Thread t. However, nothing happens and the thread continues to run. I think I'm missing something and would appreciate some help on how to properly interrupt the long running process/Thread t.
I guess specSel(args, truncate);//VERY LONG RUNNING PROCESS CALLED ONCE
doesn't support interruption.
For the interrupt mechanism to work correctly, the interrupted thread must support its own interruption.
How does a thread support its own interruption?
If the thread is frequently invoking methods that throw InterruptedException
(like Thread.sleep()
), you can handle the interrupt inside the ExceptionHandler like
try { Thread.sleep(4000); } catch (InterruptedException e) { // We've been interrupted: no more messages. return; }
What if a thread goes a long time without invoking a method that throws InterruptedException? Then it must periodically invoke Thread.interrupted, which returns true if an interrupt has been received. For example:
for (int i = 0; i < inputs.length; i++) { if (Thread.interrupted()) { // We've been interrupted: no more crunching. return; } }
Since latter be the case of you, I suggest you do the second suggestion inside specSel(args, truncate);
to support its interruption. Of course, you can do something else other than return
. But this is what you wanted.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.