将实例调用到同一线程内的线程

问题描述

上下文:

我在 java 中有一个 cmd 应用程序,它被编写为在不同的服务器上以对等模式工作。一旦服务器启动,所有其他实例必须停止。所以我写了一段代码,它运行在一个低优先级的线程中并监控一个 AtomicBooleanautoClose,每当 autoClose 设置为 true 时,线程将关闭应用程序。 (P.S.:我不想手动添加close,因为应用程序有2个主要的高优先级线程和许多临时的普通优先级线程)

代码如下:

/**
 * Watches autoClose boolean value and closes the connector once it is true
 * <p>
 * This is a very low priority thread which continuously monitors autoClose
 */
protected void watchAndClose() {
    Thread watchAutoClose = new Thread(() -> {
        while (true) {

            if (autoClose.get()) {
                close();

                // wait till closing is successful
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException ignored) {

                    // I want instance of thread watchAutoClose so I can call this
                    // watchAutoClose.interrupt();

                }
                if (!component.getStatus()) setAutoClose(false);
            }
        }
    });
    watchAutoClose.setPriority(Thread.MIN_PRIORITY);
    watchAutoClose.start();
}

问题:

SonarLint 说我不能将 InterruptedException 部分留空。我必须再次抛出它或调用 thatThread.interrupt()

那我该怎么做呢?我想要该线程内的线程 watchAutoClose 实例,以便我可以调用 watchAutoClose.interrupt()。我试过 Thread.currentThread() 但我担心有这么多线程,当前正在执行的线程不会是这个线程。 (即,JVM 有可能在位于 catch 子句中并调用 Thread.currentThread()选择切换到另一个线程,因此此时当前线程将是另一个线程我会打断另一个线程...如果我太担心或者我的概念完全错误,请纠正我。)

或者我应该完全忽略警告并离开 catch 块?

解决方法

首先,不清楚为什么您认为等待一秒钟是必要的。到 close() 方法返回时,close() 方法已经完成。另一方面,如果 close() 确实触发了一些异步操作,则无法保证等待一秒钟就足以完成。

此外,解决您的字面问题,Thread.currentThread() 始终返回调用线程的实例。线程不可能在不处于运行状态的情况下执行该方法。当任务切换发生时,线程根本无法读取引用,直到再次获得 CPU 时间。除此之外,由于规范说这个方法返回代表调用者的 Thread 实例,环境必须确保这个属性,不管它如何实现它。即使在不同的 CPU 内核上,多个线程真正同时调用此方法也能正常工作。

所以,不管等待一秒钟的方法有多么可疑,像处理中断一样

try {
    TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
    Thread.currentThread().interrupt();
}

是一种有效的方法。

但是你也可以用

替换这个代码
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));

parkNanos 方法将在中断时静默返回,使调用线程处于中断状态。因此,它与捕获 InterruptedException 并恢复中断状态具有相同的效果,但更简单且可能更高效,因为不需要构造、抛出和捕获异常。

另一点是,当变量为 false 时,您正在对消耗 CPU 周期的原子变量创建轮询循环,这是不鼓励的,即使您给线程一个低优先级。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...