所以我有一个线程,我之前无法运行,但现在已经解决了,感谢网站上的一位成员,可以找到here的问题。
要停止我的线程,我在线程类中创建了一个布尔值,并将其设置为 false ,如果设置为 true ,则线程应该停止。我甚至通过打印线程来检查何时停止线程,但它打印 true (它应该),但线程继续运行。
我的主题( CheckFiles.java )类看起来像这样。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class CheckFiles extends Thread {
static boolean stop = false;
public void run() {
while (!stop) {
System.out.println("Thread " + stop);
try {
String line;
BufferedReader b = new BufferedReader(new FileReader(UserInterface.location));
while((line = b.readLine()) != null) {
Ststem.out.println(line);
}
} catch (IOException e) { System.out.println(e); }
}
}
}
要停止线程我有一个按钮,它的代码看起来像这样。
stopChecking.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
CheckFiles.stop = true;
System.out.println(CheckFiles.stop); //Prints true when pressed
}
});
为什么我的帖子没有停止,或者有更好的方法吗?
编辑:当我尝试中断线程时,我得到了语法错误
无法从类型Thread
中对非静态方法interrupt()进行静态引用
此外,当我使布尔值停止时,线程仍在运行。
答案 0 :(得分:2)
您必须将stop
声明为volatile
:
static volatile boolean stop = false;
基本上,volatile
意味着访问volatile
字段的每个线程都将在继续之前读取其当前值,而不是(可能)使用缓存值,这似乎发生在编译器的情况下假设您的线程中stop
值始终为false,因为它从不为其写入其他值。
答案 1 :(得分:2)
线程在b.readLine()
上阻塞,因为该行代码导致线程执行停止,直到有一些输入可用。
要“强制”停止,请使用Thread.interrupt()
E.g:
stopChecking.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
//To clarify the following uses a INSTANCE of CheckFiles, called CheckFiles.
//In other words, somewhere there was a declaration with the format:
// CheckFiles CheckFiles = ...
CheckFiles.stop = true;
CheckFiles.interrupt(); //Or whatever the name of your thread instance is
System.out.println(CheckFiles.stop); //Prints true when pressed
}
});
内部阅读循环也应该这样修改:
while(!stop && (line = b.readLine()) != null){
Ststem.out.println(line);
}
由于中断只是解锁I / O,我们需要在继续进行另一次阻塞读取之前检查stop是否仍为false
。
正如其他人所建议的那样,另一种方法是在设置b.close()
后直接调用stop = true;
。
修改强>
就像Vakh所说的那样,你也应该设置你的布尔值volatile
,这样所有线程都可以立即看到stop
变量的更新。
答案 2 :(得分:0)
使用b.close()停止bufferedreader时,是否会停止该线程?
答案 3 :(得分:0)
使用线程中断标志进行终止:
public class FileChecker implements Callable<Void> {
private final File location;
public FileChecker(File location) {
this.location = location;
}
@Override
public Void call() throws Exception {
try {
while (!Thread.currentThread().isInterrupted()) {
try (BufferedReader b = new BufferedReader(new FileReader(location))) {
String line;
while ((line = b.readLine()) != null) {
if (Thread.interrupted()) {
throw new InterruptedException();
}
System.out.println(line);
}
}
}
} catch (InterruptedException ex) {
// restore interruption flag
Thread.currentThread().interrupt();
}
return null;
}
}
您现在可以使用ExecutorService
:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new FileChecker(...));
通过取消Future
或关闭执行程序来停止文件检查程序:
future.cancel(true);
executor.shutdownNow();