有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java程序不停止线程

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

为了停止我的线程,我在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

        }
    });

为什么我的线程没有停止,或者有更好的方法吗

编辑:当我试图中断线程时,我得到了语法错误

Cannot make a static reference to the non-static method interrupt() from the type Thread

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


共 (3) 个答案

  1. # 1 楼答案

    线程在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);
    }
    

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

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


    编辑:

    正如Vakh所说,您还应该设置布尔值volatile,以便所有线程都能立即看到对stop变量的更新

  2. # 2 楼答案

    使用线程中断标志终止:

    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();
    
  3. # 3 楼答案

    当您使用b.close()停止bufferedreader时,这不会停止线程吗