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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6599202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 08:05:47  来源:igfitidea点击:

How interrupt/stop a thread in Java?

javamultithreading

提问by Valter Silva

I'm trying to stop a thread but I can't do that :

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

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
}

So, even when i call the method 'stop' the thread don't stop. It keeps alive.

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

How can I interrupt/stop this thread ?

我怎样才能中断/停止这个线程?

UPDATE(@little approach)

更新(@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();
    }
}

The Middleware class :

中间件类:

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

But when I try to stop the thread, it doesn't.

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

What could be wrong in the code above ?

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

采纳答案by mre

There's really no reason you need to use a volatileflag. Instead, just query the thread for its state with isInterrupted(). Also, why are you wrapping your Scanthread object in another thread object? That seems completely unnecessary to me.

你真的没有理由需要使用volatile标志。相反,只需使用isInterrupted(). 另外,为什么要将Scan线程对象包装在另一个线程对象中?这对我来说似乎完全没有必要。

Here' what you should be doing

这是你应该做的

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

Here's an example. Also, I wouldn't recommend extending Thread.

这是一个例子。另外,我不建议扩展Thread.

回答by Leonard Brünings

Simply return;from your while and the thread will die, no need to call stop() or interrupt(). If you want to do it externally then use this pattern and call requestStop().

只需return;从您的 while 开始,线程就会死亡,无需调用 stop() 或 interrupt()。如果您想在外部执行此操作,请使用此模式并调用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;
    }

}

回答by trashgod

"Many uses of stop()should be replaced by code that simply modifies some variable to indicate that the target thread should stop running."—java.lang.Thread

“许多使用的stop()应该被替换为简单地修改一些变量以指示目标线程应该停止运行的代码。”—java.lang.Thread

回答by Jim

The usual way to stop a thread is to have a volatile flag and then check that in the run method. i.e.

停止线程的常用方法是有一个 volatile 标志,然后在 run 方法中检查它。IE

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

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

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

    public void stop(){
        stop = true;
    }
}

You can then call scan.stop().

然后就可以调用了scan.stop()

回答by Anantha Sharma

if you want to interrupt a running thread, then you need to have access to the thread object.

如果要中断正在运行的线程,则需要访问线程对象。

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

then say

然后说

thread.interrupt();

this will interrupt the running thread.

这将中断正在运行的线程。

回答by Osama Javed

Completely agree with Jim.. Just to add If your thread is blocked inside the try block for instance reading on a datastream etc then interrupt the thread as well or close the stream. In both cases the thread should be wakened up again and it will then be able to see the change in the value of "stop" boolean and die naturally by falling out of the run method. At least this is what I did to kill my threads in the shutdown thread for my server.

完全同意 Jim .. 只是补充一下 如果您的线程在 try 块内被阻塞,例如读取数据流等,则也中断线程或关闭流。在这两种情况下,线程都应该再次被唤醒,然后它将能够看到“stop”布尔值的变化,并通过退出 run 方法自然死亡。至少这是我为我的服务器在关闭线程中杀死我的线程所做的。

回答by Sylver

    public void run()
    { 
         while (!Thread.currentThread().isInterrupted()) 
         {
        //do something here
        if(condition)
       {
           Thread.currentThread().interrupt();
       }
   }

回答by wandermonk

Rather than using Thread.stop() or Thread.interrupt() you can go for the external locks. Basically, when you try to utilize an intrinsic lock most of the time any interrupt you perform on the thread is uncontrollable.

您可以使用外部锁,而不是使用 Thread.stop() 或 Thread.interrupt()。基本上,当您在大多数情况下尝试使用内在锁时,您在线程上执行的任何中断都是无法控制的。

A re-entrant lock provides you the methods as mentioned below

可重入锁为您提供了如下所述的方法

lock() 
unlock() 
tryLock() 
lockInterruptibly() 
isHeldByCurrentThread() 
getHoldCount() 

Check the below example

检查下面的例子

final ReentrantLock reentrantLock = new ReentrantLock();    
    @Override
    public void performTask() {
        reentrantLock.lock();
        try { 
             System.out.println(Thread.currentThread().getName() + ": Lock acquired.");
             System.out.println("Processing...");
             Thread.sleep(2000);
        } catch (InterruptedException e) {
             e.printStackTrace();
        } finally {
             System.out.println(Thread.currentThread().getName() + ": Lock released.");
         reentrantLock.unlock();
            }
    }

This makes your code elegant and handle the interrupt in a better way.

这使您的代码优雅并以更好的方式处理中断。