- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 Java 应用程序,其中有一些无限运行的线程轮询后端数据库。当 JVM 关闭时(通过 weblogic UI),我需要为每个线程执行一些清理操作,例如连接到数据库并将正在运行的事务的状态从“进行中”设置为“未处理”。
有没有办法在每个线程中编写一个方法,当线程将被 JVM 停止时调用该方法?
我了解关闭 Hook ,但我需要线程中变量的数据来了解 Db 中要更改的状态,并且在关闭 Hook 的实现中,似乎启动了一个单独的 Hook 线程,该线程不会包含来自原始线程。
最佳答案
既然您可以访问这些线程(我的意思是您可以修改它们的代码),那么您可以:
JFrame
,则添加 windowClosing()
Hook 以优雅地停止正在运行的 Thread
,同时将框架的默认关闭操作设置为DO_NOTHING_ON_CLOSE。看看下面这个答案中我的代码...线程
退出循环。Thread
将进行任何必要的更改(可以完全访问其所有变量),然后退出 run()
方法。<Thread
(即标记所有其他Thread
停止的Thread
)中,您将join()
每个有限线程
。Thread
完全执行(即退出其 run()
方法)。线程
将调用例如 System.exit(0);
来退出整个应用程序,因为这应该是用户最后想要的操作。注意:这假设用户将通过正常操作关闭应用程序。例如,如果用户要通过 Windows 的任务管理器终止应用程序,则此方法将不起作用。我不知道 Thread
上的关闭 Hook ...
遵循示例代码(阅读注释):
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class GraceDown {
private static class MyThread extends Thread {
private boolean keepGoing = true; //This is the stopping flag.
private final int i; //In this case i marks the 'id' of the Thread, but it is also an arbitary variable that the Thread has acccess in its final moments...
public MyThread(final int i) {
this.i = i;
}
private synchronized boolean isKeepGoing() {
return keepGoing; //Tells if we should exit the loop and start the stopping operation...
}
public synchronized void startShutdown() {
keepGoing = false; //Tells we should exit the loop and start the stopping operation.
}
@Override
public void run() {
while (isKeepGoing()) { //After every complete loop, we check the if we can go on.
//Your 'infinite' loop actions go in here:
try { Thread.sleep(1000); } catch (final InterruptedException ie) {}
System.out.println("Thread " + i + " running...");
}
//Your gracefull shutdown actions go here...
System.out.println("Thread " + i + ": my stopping actions go here! Look, I have access to all my variables (such as i)! ;)");
}
}
public static void main(final String[] args) {
//Create and start the Threads:
final MyThread[] myThreads = new MyThread[5];
for (int i = 0; i < myThreads.length; ++i)
myThreads[i] = new MyThread(i);
for (int i = 0; i < myThreads.length; ++i)
myThreads[i].start();
final JFrame frame = new JFrame("Lets close me...");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //IMPORTANT STEP! This means we are going to close the application instead of it being closed automatically when the user presses to close the window...
//Adding the 'hook':
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent wevt) {
System.out.println("Initializing shutdown...");
//This is where the thread is going to stop all others...
for (int i = 0; i < myThreads.length; ++i)
myThreads[i].startShutdown();
//Wait for all threads to stop:
for (int i = 0; i < myThreads.length; ++i)
try { myThreads[i].join(); } catch (final InterruptedException ie) { System.err.println("Error gracefully shutdowning the Thread!!!"); }
//Now we can exit the JVM:
System.out.println("Exiting JVM...");
System.exit(0); //Code '0' indicates exiting without error(s).
}
});
frame.getContentPane().add(new JLabel("Close this window and the Threads will shutdown gracefully...", JLabel.CENTER));
frame.pack();
frame.setLocationRelativeTo(null); //Put the packed frame on the center of the default screen.
frame.setVisible(true);
}
}
上面应该打印这样的内容:
线程 1 正在运行...
线程 4 正在运行...
线程 0 正在运行...
线程 2 正在运行...
线程 3 正在运行...
线程 3 正在运行...
线程 4 正在运行...
线程 2 正在运行...
线程 1 正在运行...
线程 0 正在运行...
正在初始化关闭...
线程 2 正在运行...
主题 2:我的停止 Action 放在这里!看,我可以访问我的所有变量(例如 i)! ;)
线程 0 正在运行...
线程 0:我的停止 Action 放在这里!看,我可以访问我的所有变量(例如 i)! ;)
线程 1 正在运行...
线程 4 正在运行...
线程 3 正在运行...
主题 3:我的停止 Action 放在这里!看,我可以访问我的所有变量(例如 i)! ;)
主题 4:我的停止 Action 放在这里!看,我可以访问我的所有变量(例如 i)! ;)
主题 1:我的停止 Action 放在这里!看,我可以访问我的所有变量(例如 i)! ;)
退出 JVM...
这是我在您所描述的问题中看到的一个最小解决方案。
关于JVM 关闭前 Java 轮询器线程清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52379786/
我是一名优秀的程序员,十分优秀!