如何在Java中中断/停止线程?

2022-09-03 08:51:38

我试图停止一个线程,但我不能这样做:

public class Middleware {

public void read() {
    try {
        socket = new Socket("192.168.1.8", 2001);

        // code .. 

        Scan scan = new Scan();
        thread = new Thread(scan);
        thread.start();

    } catch (UnknownHostException ex) {
        ex.printStackTrace();

    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

class Scan extends Thread {

    public void run() {

        while (true) {
            try {
            // my code goes here

            } catch (IOException ex) {
                thread.currentThread().interrupt();
            }
        }
    }
}

public void stop() {
    Thread.currentThread().interrupt();
}

// get and setters
}

所以,即使我调用方法“stop”,线程也不会停止。它保持活力。

如何中断/停止此线程?

更新(@little方法)

private void tb_startActionPerformed(java.awt.event.ActionEvent evt) {                                         
    Middleware middleware = new Middleware();

    if (tb_start.getText().equals("Start")){
        tb_start.setText("Stop");

        // starting to read rfid tags
        middleware.read();
    }else{
        tb_start.setText("Start");

        // stop reading rfid tags
        middleware.stop();
    }
}

中间件类:

public class Middleware {

    private Scan scan;

    public void read() {

        scan = new Scan();
        scan.start();
    }

    private class Scan extends Thread {

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("reading...");
            }
        }
    }

    public void stop() {
        if (scan != null) {
            scan.interrupt();
        }
    }
}

但是当我尝试停止线程时,它没有。

上面的代码中可能有什么问题?


答案 1

你真的没有理由需要使用标志。相反,只需使用 isInterrupted() 查询线程的状态。另外,为什么要将线程对象包装在另一个线程对象中?这在我看来是完全没有必要的。volatileScan

这是你应该做的

public class Middleware {
    private Scan scan;

    public void read() {
        try {
            // do stuff

            scan = new Scan();
            scan.start();
        } catch (UnknownHostException ex) {
            // handle exception
        } catch (IOException ex) {
            // handle exception
        }
    }

    private class Scan extends Thread {

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    // my code goes here
                } catch (IOException ex) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }

    public void stop() {
        if(scan != null){
            scan.interrupt();
        }
    }
}

下面是一个示例。另外,我不建议扩展.Thread


答案 2

只需从你的同时开始,线程就会死,无需调用 stop() 或 interrupt()。如果要在外部执行此操作,请使用此模式并调用 。return;requestStop()

class Scan extends Thread {
    private volatile stop = false;
    public void run() {

        while (!stop) {
            try {
            // my code goes here

            } catch (IOException ex) {
                stop = true;
            }
        }
    }

    public void requestStop() {
        stop = true;
    }

}