Java 程序不停止线程
因此,我有一个线程,我以前无法运行,但现在已经解决了感谢在这个网站上的成员,这个问题可以找到 为了停止我的线程,我在thread类中创建了一个布尔值,并将其设置为false,如果设置为true,那么线程应该停止。我甚至通过打印线程来检查何时停止线程,但它打印true(它应该这样做),但线程继续运行 我的线程(CheckFiles.java)类如下所示Java 程序不停止线程,java,multithreading,Java,Multithreading,因此,我有一个线程,我以前无法运行,但现在已经解决了感谢在这个网站上的成员,这个问题可以找到 为了停止我的线程,我在thread类中创建了一个布尔值,并将其设置为false,如果设置为true,那么线程应该停止。我甚至通过打印线程来检查何时停止线程,但它打印true(它应该这样做),但线程继续运行 我的线程(CheckFiles.java)类如下所示 import java.io.BufferedReader; import java.io.FileReader; import java.io.
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
}
});
为了停止线程,我有一个按钮,它的代码如下所示
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
}
});
为什么我的线程没有停止,或者有更好的方法吗
编辑:当我试图中断线程时,我得到了语法错误
无法从类型线程对非静态方法interrupt()进行静态引用
另外,当我将布尔停止设置为volatile时,线程仍在运行。您必须将
停止
声明为volatile
:
static volatile boolean stop = false;
基本上,
volatile
意味着访问volatile
字段的每个线程都将在继续之前读取其当前值,而不是(可能)使用缓存值,这似乎发生在编译器假定线程中的stop
值始终为false的情况下,因为它从未为其写入其他值。必须将stop
声明为volatile
:
static volatile boolean stop = false;
基本上,
volatile
意味着访问volatile
字段的每个线程都将在继续之前读取其当前值,而不是(可能)使用缓存值,这似乎发生在编译器假设线程中的stop
值始终为false的情况下,因为它从未为它写入其他值。线程在b.readLine()
上阻塞,因为该行代码导致线程执行停止,直到有可用的输入
要“强制”停止,请使用Thread.interrupt()
例如:
内部读数回路也应进行如下修改:
while(!stop && (line = b.readLine()) != null){
Ststem.out.println(line);
}
由于中断只是解除了I/O的阻塞,在继续执行另一次阻塞读取之前,我们需要检查stop是否仍然是false
正如其他人所建议的,另一种方法是在设置stop=true之后直接调用b.close()
代码>
编辑:
正如Vakh所说,您还应该将布尔值设置为volatile
,以便所有线程都能立即看到stop
变量的更新。线程在b.readLine()
上阻塞,因为该行代码会导致线程执行暂停,直到有可用的输入
要“强制”停止,请使用Thread.interrupt()
例如:
内部读数回路也应进行如下修改:
while(!stop && (line = b.readLine()) != null){
Ststem.out.println(line);
}
由于中断只是解除了I/O的阻塞,在继续执行另一次阻塞读取之前,我们需要检查stop是否仍然是false
正如其他人所建议的,另一种方法是在设置stop=true之后直接调用b.close()
代码>
编辑:
正如Vakh所说,您还应该将布尔值设置为volatile
,以便所有线程都能立即看到对stop
变量的更新。当您使用b.close()停止bufferedreader时,会不会停止线程?当您使用b.close()停止bufferedreader时,这不会停止线程吗?使用线程中断标志终止:
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;
}
}
通过取消未来
或关闭执行器停止文件检查器:
future.cancel(true);
executor.shutdownNow();
使用线程中断标志终止:
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;
}
}
通过取消未来
或关闭执行器停止文件检查器:
future.cancel(true);
executor.shutdownNow();
你有两个虫子;您需要同时使用volatile
和中断阻塞线程;这是一个复制品,但我还不能在几分钟内将其标记为复制品;您需要同时使用volatile
和中断阻塞线程;这是一个重复,但我还不能在几分钟内将其标记为重复。即使声明为volatile,线程仍在运行它。即使声明为volatile,线程仍在运行它。我不能中断线程,在原始帖子中添加了错误。@user2612619您需要注意的几件事。1.不要将stop变量设置为static,否则当您可能只想停止一个线程时,您将停止所有线程。2.对实际的线程实例对象执行interrupt()
方法。通过执行CheckFile.interrupt()
可以静态地访问interrupt()
方法,因为您是通过类而不是实例直接引用它。如果我不将变量设置为静态,则无法从按钮所在的另一个方法访问它。另外,我正在打断它,就像您在示例中所做的那样。@user2612619这是我的观点,您不应该试图用静态方法修改一个线程实例的状态。我的示例只是假设您有一个名为CheckFiles
的对象实例(请参见语句后的注释),那么我应该如何更改线程的状态?我目前只有一个线程在运行。我不能中断线程,在原始帖子中添加了错误。@user261261619您需要注意的几件事。1.不要将stop变量设置为static,否则当您可能只想停止一个线程时,您将停止所有线程。2.对实际的线程实例对象执行interrupt()
方法。通过执行CheckFile.interrupt()
静态访问interrupt()
方法,因为