Java 程序不停止线程

Java 程序不停止线程,java,multithreading,Java,Multithreading,因此,我有一个线程,我以前无法运行,但现在已经解决了感谢在这个网站上的成员,这个问题可以找到 为了停止我的线程,我在thread类中创建了一个布尔值,并将其设置为false,如果设置为true,那么线程应该停止。我甚至通过打印线程来检查何时停止线程,但它打印true(它应该这样做),但线程继续运行 我的线程(CheckFiles.java)类如下所示 import java.io.BufferedReader; import java.io.FileReader; import java.io.

因此,我有一个线程,我以前无法运行,但现在已经解决了感谢在这个网站上的成员,这个问题可以找到

为了停止我的线程,我在thread类中创建了一个布尔值,并将其设置为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

        }
    });
为了停止线程,我有一个按钮,它的代码如下所示

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()
方法,因为