You have a misconception about how thread interruption works, when you call Thread#interrupt
all that happens is a flag
is raised within the Thread
instance, which you can inspect using a interrupted
or isInterrupted
.
In your code, you have a for-loop
for (int i = 0; i < podSoubory.length; i++) {
if (podSoubory[i].isDirectory()) {
String tempPath = podSoubory[i].getAbsolutePath();
System.out.println(tempPath);
if (podSoubory[i].isFile()) {
fileCount++;
}
}
This means that until this for-loop
exists, the while(!thread.interrupted()){
statement won't be evaluated.
What you need to do is test isInterrupted
at periodalical points within your code, for example...
for (int i = 0; i < podSoubory.length && !Thread.currentThread().isInterrupted(); i++) {
if (podSoubory[i].isDirectory()) {
String tempPath = podSoubory[i].getAbsolutePath();
System.out.println(tempPath);
if (podSoubory[i].isFile()) {
fileCount++;
}
}
}
This adds a check for isInterrupted
, this is imported, as isInterrupted
WON'T clear the interrupted flag like Thread#interrupted
will, this allows other parts of your code to further test the interrupted
flag as well.
When you interrupt your Thread
, both the for-loop
AND while-loop
will check the state of the interrupted
flag and will allow both loops to exit.
As a runnable example...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MyApp {
public static void main(String[] args) {
new MyApp();
}
public MyApp() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton stop = new JButton("Stop");
stop.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
thread.interrupt();
// Join is used here to prove a point, be careful
// with using this within the context of the EDT
try {
thread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
stop.setEnabled(false);
}
});
add(stop);
scanningMethod();
}
Thread thread;
int fileCount = 0;
String path = "C:\\Program Files";
public void scanningMethod() {
thread = new Thread(new Runnable() {
public void run() {
while (!thread.isInterrupted()) {
//Recursion method that counting files
dirScan(path);
System.out.println(thread.isInterrupted());
}
}
});
thread.start();
}
private void dirScan(String dirPath) {
File[] podSoubory = new File(dirPath).listFiles();
for (int i = 0; i < podSoubory.length && !Thread.currentThread().isInterrupted(); i++) {
if (podSoubory[i].isDirectory()) {
String tempPath = podSoubory[i].getAbsolutePath();
System.out.println(tempPath);
if (podSoubory[i].isFile()) {
fileCount++;
}
}
}
}
}
}
You might want to have a look at Concurrency in Java for more details
Also, Thread#stop
is deprecated and should NEVER be used, from the JavaDocs...
Deprecated. This method is inherently unsafe. Stopping a thread with
Thread.stop causes it to unlock all of the monitors that it has locked
(as a natural consequence of the unchecked ThreadDeath
exception
propagating up the stack). If any of the objects previously protected
by these monitors were in an inconsistent state, the damaged objects
become visible to other threads, potentially resulting in arbitrary
behavior. Many uses of stop should be replaced by code that simply
modifies some variable to indicate that the target thread should stop
running. The target thread should check this variable regularly, and
return from its run method in an orderly fashion if the variable
indicates that it is to stop running. If the target thread waits for
long periods (on a condition variable, for example), the interrupt
method should be used to interrupt the wait. For more information, see
Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.