程序不停止线程

时间:2013-11-09 23:09:51

标签: java multithreading

所以我有一个线程,我之前无法运行,但现在已经解决了,感谢网站上的一位成员,可以找到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()进行静态引用

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

4 个答案:

答案 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();