将实例调用到同一线程内的线程
Calling the instance to the thread inside that same thread
上下文:
我在 java 中有一个 cmd 应用程序,它被编写为在不同服务器上以对等模式工作。服务器启动后,所有其他实例都必须停止。因此,我编写了一段代码,它在低优先级线程中运行并监视 AtomicBoolean 值 autoClose
,只要 autoClose 设置为 true,线程就会关闭应用程序。 (P.S.: 我不想手动添加关闭,因为应用程序有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()
时,JVM 有可能 选择切换 到另一个线程,因此此时当前线程将是另一个,我会打断另一个线程... 如果我太担心或者我的概念完全错误,请纠正我。)
或者我应该完全忽略警告并离开 catch 块吗?
首先,不清楚为什么您认为有必要等待一秒钟。到close()
方法return秒时,close()
方法已经完成。另一方面,如果 close()
确实触发了一些异步操作,则不能保证等待一秒钟就足以完成。
此外,解决你的字面问题,Thread.currentThread()
总是return调用线程的实例。线程不可能在不处于 运行 状态的情况下执行该方法。当任务切换发生时,线程根本无法读取引用,直到它再次获得 CPU 时间。除此之外,由于规范说此方法 return 是代表调用者的 Thread
实例,环境必须确保此 属性,无论它如何实现它。即使多个线程在不同的 CPU 核心上同时真正调用此方法,它也能正常工作。
所以,不管等待一秒钟的方法有多么可疑,处理中断就像
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
是一种有效的方法。
但您也可以将此代码替换为
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
parkNanos
方法将return 静默中断,使调用线程处于中断状态。因此它与捕获 InterruptedException
并恢复中断状态具有相同的效果,但更简单并且可能更有效,因为不需要构造、抛出和捕获异常。
另一点是,当变量为 false 时,您正在对消耗 CPU 周期的原子变量创建轮询循环,这是不鼓励的,即使您为线程设置了低优先级。
上下文:
我在 java 中有一个 cmd 应用程序,它被编写为在不同服务器上以对等模式工作。服务器启动后,所有其他实例都必须停止。因此,我编写了一段代码,它在低优先级线程中运行并监视 AtomicBoolean 值 autoClose
,只要 autoClose 设置为 true,线程就会关闭应用程序。 (P.S.: 我不想手动添加关闭,因为应用程序有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()
时,JVM 有可能 选择切换 到另一个线程,因此此时当前线程将是另一个,我会打断另一个线程... 如果我太担心或者我的概念完全错误,请纠正我。)
或者我应该完全忽略警告并离开 catch 块吗?
首先,不清楚为什么您认为有必要等待一秒钟。到close()
方法return秒时,close()
方法已经完成。另一方面,如果 close()
确实触发了一些异步操作,则不能保证等待一秒钟就足以完成。
此外,解决你的字面问题,Thread.currentThread()
总是return调用线程的实例。线程不可能在不处于 运行 状态的情况下执行该方法。当任务切换发生时,线程根本无法读取引用,直到它再次获得 CPU 时间。除此之外,由于规范说此方法 return 是代表调用者的 Thread
实例,环境必须确保此 属性,无论它如何实现它。即使多个线程在不同的 CPU 核心上同时真正调用此方法,它也能正常工作。
所以,不管等待一秒钟的方法有多么可疑,处理中断就像
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
是一种有效的方法。
但您也可以将此代码替换为
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
parkNanos
方法将return 静默中断,使调用线程处于中断状态。因此它与捕获 InterruptedException
并恢复中断状态具有相同的效果,但更简单并且可能更有效,因为不需要构造、抛出和捕获异常。
另一点是,当变量为 false 时,您正在对消耗 CPU 周期的原子变量创建轮询循环,这是不鼓励的,即使您为线程设置了低优先级。