1

所以我有一个线程,我以前无法运行,但由于这个站点上的一个成员,这个问题现在已经解决了,这个问题可以在这里找到。

为了停止我的线程,我在线程类中创建了一个布尔值并将其设置为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() 进行静态引用

此外,当我使布尔停止 volatile 时,线程仍在运行。

4

4 回答 4

2

您必须声明stopvolatile

static volatile boolean stop = false;

基本上,volatile意味着访问volatile字段的每个线程都会在继续之前读取其当前值,而不是(可能)使用缓存值,这似乎发生在编译器假定stop线程中的值始终为假的情况下,因为它从不为其写入另一个值。

于 2013-11-09T23:12:22.903 回答
2

线程正在阻塞,b.readLine()因为那行代码导致线程执行停止,直到有一些输入可用。

要“强制”停止,请使用Thread.interrupt()

例如:

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);
}

false由于中断只是解除对 I/O 的阻塞,我们需要在继续进行另一次阻塞读取之前检查停止是否仍然存在。

b.close()正如其他人所建议的那样,另一种方法是在设置之后直接调用stop = true;


编辑:

正如 Vakh 所说,您还应该将您的布尔值设为布尔值volatile,以便对stop变量的更新立即对所有线程可见。

于 2013-11-09T23:12:23.280 回答
0

当你用 b.close() 停止 bufferedreader 时,不会停止线程吗?

于 2013-11-09T23:26:18.770 回答
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();
于 2013-11-09T23:30:00.537 回答