【问题标题】:How can I interrupt a thread created from within a method?如何中断从方法中创建的线程?
【发布时间】:2015-08-18 23:05:17
【问题描述】:

我知道您可以中断从可运行类创建的线程,但是如何中断从方法创建的线程?使用 volatile 布尔值对我不起作用,所以我认为要么有更好的方法来做到这一点,要么我需要以某种方式中断它。我不想打断所有线程,就这一个。

我创建了一个启动线程的方法,如下所示:

public static void StartSyncThread() {
        new Thread() {
            public void run() {
                    isRunning = true;  // Set to true so while loop will start

                    while (isRunning) {
                        ...
                        }

            } // Close run()
        }.start();

    }

....

public static void KillSyncThread() {
    isRunning = false;
}

【问题讨论】:

  • 这应该可以。即使您没有提供 isRunning 声明,它也只有在 isRunning 被声明为封闭类的 boolean 静态时才会编译。
  • 它不起作用。即使布尔值是不稳定的。当我调用 kill 时,它会继续运行。
  • 您能提供isRunning 声明吗?我假设它被声明为封闭类的静态。也许您不小心在isRunning = true; 行中添加了boolean,而run() 方法没有对其他isRunning 变量进行更改?
  • public static volatile boolean isRunning = true
  • 请提供 MCVE。

标签: java multithreading thread-safety java-threads interruption


【解决方案1】:

如果您保留对线程的引用:

private static Thread myThread;

public static void StartSyncThread() {
    myThread = new Thread() {
        public void run() {    
            while (!Thread.currentThread().isInterrupted()) {
                        ...
            }

        } // Close run()
    }
    myThread.start();
}

那你就可以打电话了

public static void killSyncThread() {
    if (myThread != null && myThread.isAlive()) {
        myThread.interrupt();
    }
}

取消它。这样你就可以摆脱静态 isRunning 标志,interrupt() 设置一个与之等效的内置标志,另外它会将线程从睡眠或等待中唤醒。

如果您确实将变量声明为 volatile,那么它的更新值应该在线程间可见。可能这是一个范围界定问题,您正在测试的标志与您设置的标志不同?对于全局可变状态,它似乎可能会很快变得复杂。做一个小例子,自己验证设置标志​​或中断线程是否有效,然后有信心找到真正的问题。

【讨论】:

    【解决方案2】:

    在您调用 KillSyncThread 之前,您的代码可能不会真正启动线程。如果是这种情况,那么线程会将 isRunning 设置为 true,然后继续永远运行。我会在你启动线程之前将 isRunning 设置为 true。

    如果

    中的代码也将无法停止

    ...

    具有无限内循环或对阻塞函数(如套接字读取)的调用。

    【讨论】:

    • 我通过单击按钮发送了KillSyncThread(),因此我调用Class.KillSyncThread();,并在线程运行后调用它。我正在使用 system.out。判断它是否正在运行。
    猜你喜欢
    • 1970-01-01
    • 2015-10-31
    • 2019-07-01
    • 1970-01-01
    • 2022-09-30
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    相关资源
    最近更新 更多